How to send an event signal through Processes - C

I have an application consisting of two windows, one communicates with the other and sends it a structure containing two integers (in this case, two rolls of bone).

I will use events for the following circumstances:

  • Process send data for processing b, process b displays data
  • The process closes, in turn, the closing process b
  • Process b closes a, in turn, closes a

I noticed that if the second process is constantly waiting for the first process to send data, then the program will just sit waiting, as a result of which the idea of โ€‹โ€‹implementing threads for each process came up, and I started to implement it already.

The problem I am facing is that I do not have much experience with streams and events, so I am not sure that you can really implement what I want to do.

Iโ€™m trying to understand how another process will know about the dismissed event, so that it can carry out the tasks that it should perform, I donโ€™t understand how one process, which is separated from another, can say that the states of the event occur in particular, since it must act as soon as the event has changed.

Thanks for any help

Edit:

I can only use Create / Set / Open methods for events, sorry for not mentioning this before.

In addition , I create a new thread in process A, which allows the user to interact with the application while listening to the close event.

Create stream:

hCreateEventThread = CreateThread( NULL, // lpThreadAttributes (default) 0, // dwStackSize (default) ThreadFunc, // lpStartAddress NULL, // lpParameter 0, // dwCreationFlags &hCreateEventThreadID // lpThreadId (returned by function) ); if(hCreateEventThread != NULL) { MessageBox(hMainWindow,L"Thread created!",L"Success!",MB_OK); } 

Opening event A when B closes :

  DWORD WINAPI ThreadFunc(LPVOID passedHandle) { hConsumerCloseEvent = OpenEvent(EVENT_ALL_ACCESS, FALSE, TEXT("Global\\ConsumerCloseEvent")); while(TRUE) { dwCloseResult = WaitForSingleObject(hConsumerCloseEvent,INFINITE); switch (dwCloseResult) { // State of object is signalled case WAIT_OBJECT_0: //Consumer has closed, exit program. //CloseHandle(hDiceRoll); //CloseHandle(hCloseEvent); //CloseHandle(hCreateEventThread); ExitProcess(1); break; default: return; } } } 

Creating an event in b (In WM_CREATE):

 hConsumerCloseEvent = CreateEvent( NULL, // default security attributes TRUE, // manual-reset event TRUE, // initial state is nonsignaled TEXT("Global\\ConsumerCloseEvent") // object name ); if(hConsumerCloseEvent == NULL) { MessageBox(hMainWindow,L"CreateEvent failed",L"Error",MB_OK); } 

Setting an event for an alarm when B closes:

 case WM_DESTROY: { SetEvent(hConsumerCloseEvent); PostQuitMessage(0); break; } 

As you can see, when the event is signaled, application A is set to close. When I start both applications and close process B, process A does not notice the changed signal and does not close.

Edit 2:

After using GetLastError (); I was able to determine that the OpenEvent descriptor is NULL, the error indicated

ERROR_FILE_NOT_FOUND - 2: the system cannot find the specified file

Whether my method of creating an event and reading it is incorrect, I have definitely included the Global \ prefix.

+6
c multithreading events process winapi
source share
2 answers

The good thing about semaphores is that they alone take care of synchronizing the depth of the queue between the two processes. Since you are limited to using Event objects, instead I suggest having interprocess messages instead of a queue, or one queue if you do.

Process a

 // In the initialization code ... hMessageEmptiedEvent = CreateEvent(NULL, FALSE, TRUE, _T("MessageEmptied")); hMessageSentEvent = CreateEvent(NULL, FALSE, FALSE, _T("MessageSent")); // Call this function when you want to send the data to process b void sendData(struct diceData data) { // Make sure any pre-existing message has been processed WaitForSingleObject(hMessageEmptiedEvent, INFINITE); // Copy the data into the shared buffer *(struct diceData *) pBuf = data; // Signal the other process that data is ready SetEvent(hMessageSentEvnt); } 

Process b

 // In the initialization code ... hMessageEmptiedEvent = CreateEvent(NULL, FALSE, TRUE, _T("MessageEmptied")); hMessageSentEvent = CreateEvent(NULL, FALSE, FALSE, _T("MessageSent")); // Call this function when you want to recieve data from process a struct diceData readData() { struct diceData data; // Wait for a message to become available WaitForSingleObject(hMessageSentEvent, INFINITE); // Copy the data from the shared buffer data = * (struct diceData *)pBuf; // Signal the other process that message has been read. SetEvent(hMessageEmptiedEvnt); } 

If, as I assume, you really want the queue to be longer than one, you can now implement the queue logic in process b. You will want to do this in a separate thread for several reasons. The implementation of the queue logic is up to you. Depending on your performance needs, this can be a circular array or a linked list or.

 // In process b initialzation add a thread to do the queueing initializeEmptyQueue(); hQueueingThread = CreateThread(NULL, 0, enqueueLoop, NULL, 0, NULL); DWORD enqueueLoop(LPVOID ignored) { while (TRUE) { struct diceData data; data = getData(); enqueueData(data); } } 
+3
source share

Looks like you can use CreateSemaphore . A semaphore can be used to represent the number of data elements available to process process b. Initialize it to 0 when the data item becomes available, incrementing it with ReleaseSemaphore . Then in your process b call WaitForSingleObject or one of its bretheren, which will return only when the semaphore count is above 0, and at that moment the count decreases.

This is an incomplete solution because you still need to handle things like what you need to do when your shared buffer is full, but you should be good and really started.

+2
source share

All Articles