How to make an automatic interchange for 3 process

2019-09-17 22:58发布

I have 3 programs, each of them need to write 1000 times in one file. Mutex must switch programs after every 10 writings

#include "stdafx.h"
#include <Windows.h>
#include <fstream>
#include <iostream>
using namespace std;
HANDLE ghMutex;


void write()
{
    ghMutex = OpenMutex(SYNCHRONIZE, false, (LPTSTR)"WriteData");
    for (int i=0; i<100; i ++) { 
            WaitForSingleObject(ghMutex, INFINITE);
            ofstream f1("c:\\write.txt", ios_base::app);
            for (int j=0; j<10; j++)
                    f1 << 2;        
            ReleaseMutex(ghMutex);
            f1.close();
            Sleep(100);
    }
}

void main(){
write();
}

First program with "f1 << 1" and second with "f1 << 2" They aren't synchronize, how to make it? Help me to do it with 2 programs for beginning, please.

2条回答
不美不萌又怎样
2楼-- · 2019-09-17 23:58

It's not clear from your descriptions exactly how you want your program to behave. Do you want the program to guarantee that the processes alternate, if so, do you want a round-robin type ordering (e.g. process 1, then process 2, then process 3, then process 1 again)?

However, it's clear that your current mutex usage is incorrect. First, at least one process must call CreateMutex() to actually create the mutex (or else there is no mutex to open). Since the documentation for CreateMutex() says:

If lpName matches the name of an existing named mutex object, this function requests the MUTEX_ALL_ACCESS access right.

Assuming requesting more access is not a problem for you (it rarely is), then you can just have all instances call CreateMutex() ensuring that they all share the same mutex and whichever starts first actually creates is.

This is a simple example with processes that alternate in an unpredictable order (repeats are allowed), but correctly write to the file 10 times in a row without being interrupted by concurrent writers.

#include <Windows.h>
#include <conio.h>
#include <iostream>
#include <fstream>

int main ( int, char ** )
{
    // get a named mutex.  open the same mutex as other
    // concurrent instances.
    const ::HANDLE mutex = ::CreateMutexW(0, FALSE, L"Fubar");
    if (mutex == INVALID_HANDLE_VALUE)
    {
        const ::DWORD error = ::GetLastError();
        std::cerr
            << "Could not open mutex (" << error << ")."
            << std::endl;
        return (EXIT_FAILURE);
    }

    // open the input file.  notice the flags, you need to make
    // sure the 2nd process doesn't overwrite whatver the first
    // wrote, etc.
    std::ofstream file("foo.txt", std::ios::app);
    if (!file.is_open())
    {
        std::cerr
            << "Could not open file."
            << std::endl;
        return (EXIT_FAILURE);
    }

    // wait for user to unblock after launch.  this gives time
    // to start concurrent processes before we write to the
    // file.
    ::getch();

    // not sure how your application goes, but lets just
    // repeatedly write to the file until we're fed up.
    for (int j=0; j < 100; ++j)
    {
        // lock the mutex around the code that writes to the
        // file in a loop.
        ::WaitForSingleObject(mutex, INFINITE);
        for (int i=0; i < 10; ++i) {
            file << "process " << ::GetCurrentProcessId() << std::endl;
        }
        ::ReleaseMutex(mutex);

        // slow down so the application doesn't finish before we
        // unblock concurrent instances.
        ::Sleep(100);
    }

    // don't forget to clean up!
    ::CloseHandle(mutex);
}

Start multiple instances of this process (2 or more) and when all are launched, press a single key in each console window to have the processes start writing. The output file will contain burts of 10 outputs for each process.

查看更多
爷的心禁止访问
3楼-- · 2019-09-18 00:00

Is ghMutex valid in any of the processes ? What about the value returned by GetLastError() after OpenMutex() and WaitForSingleObject() ?

You need to create the mutex in one of the processes before other processes can open it. Fortunately, CreateMutex does exactly what you need: it creates the mutex if it does not exist, and opens it it if does.

And you may want to close the stream before (not after) releasing the mutex, so that cached data is flushed before other processes start writing.

查看更多
登录 后发表回答