I am in the midst of developing two applications that communicate using a file. These applications are running on the same machine. To be clear, I have a writer.exe
and a reader.exe
executables.
The writer.exe
constantly writes a random integer to a common file "some_file.bin"
and closes the file. It repeats the same process again: opens the file, writes random int
and closes it. This is done in a while loop.
The reader.exe
is constantly reading the file "some_file.bin"
, printing the read integer to its console.
Both of these applications are written in C using the std::fstream
class for file I/O.
So far, this is not working properly, because we have a race condition happening here.
I want some way to properly communicate between these two processes, using Win32 Events, so that the writer.exe
process knows to wait until the reader.exe
process has finished reading, and the reader.exe
process knows to pause until the writer.exe
process has finished writing.
I'm hoping to do this using the CreateEvent
, WaitForSingleObject
family of API calls present natively on the Windows platform.
Please feel free to tell me if this is possible between two processes?
So far, I have only found examples using the above APIs to signal threads of one main process... ?
CodePudding user response:
Yes, it is possible. When one process creates a handle to an Event object, you have the option of assigning a name to that object in the kernel. The other process can then create/open its own handle to that Event object using the same name.
Note that to accomplish what you want, you actually would need 2 Events, eg:
writer.exe:
HANDLE hReadable = CreateEvent(NULL, FALSE, FALSE, TEXT("ReaderCanRead"));
if (!hReadable) ...
HANDLE hWritable = CreateEvent(NULL, FALSE, TRUE, TEXT("WriterCanWrite"));
if (!hWritable) ...
...
while (!quit)
{
...
WaitForSingleObject(hWritable, INFINITE);
if (quit) break;
// write int...
SetEvent(hReadable);
...
}
reader.exe:
HANDLE hReadable = CreateEvent(NULL, FALSE, FALSE, TEXT("ReaderCanRead"));
// or: HANDLE hReadable = OpenEvent(SYNCHRONIZE, FALSE, TEXT("ReaderCanRead"));
if (!hReadable) ...
HANDLE hWritable = CreateEvent(NULL, FALSE, TRUE, TEXT("WriterCanWrite"));
// or: HANDLE hWritable = OpenEvent(EVENT_MODIFY_STATE, FALSE, TEXT("WriterCanWrite"));
if (!hWritable) ...
...
while (!quit)
{
...
WaitForSingleObject(hReadable, INFINITE);
if (quit) break;
// read int...
SetEvent(hWritable);
...
}
That being said, you might consider using a named block of shared memory via CreateFileMapping()
MapViewOfFile()
, rather than using a physical file.
However, there are many other Inter-Process Communication mechanisms that are way more suitable to your producer/consumer model than using a shared file/memory protected by Events. Pipes, sockets, mailslots, even window messages, would be a much better choice.