Как отправить сигнал События посредством Процессов - C

У меня есть приложение, состоящее из двух окон, каждый связывается с другой и отправляет ему структуру constaining два целых числа (В этом случае два списка игры в кости).

Я буду использовать события для следующих обстоятельств:

  • Обработайте, отправляет данные, чтобы обработать b, обработать данные дисплеев b
  • Обработайте завершения, в свою очередь закрыв процесс b
  • Обработайте завершения b a, в свою очередь закрыв процесс a

Я заметил, что, если второй процесс постоянно ожидает первого процесса для отправки данных затем, программа будет просто находиться, ожидая, который является, где идея реализовать потоки на каждом процессе произошла, и я начал уже реализовывать это.

Проблема, которую я имею, состоит в том, что у меня точно нет большого опыта с потоками и событиями, таким образом, я не уверен в лучшем способе на самом деле реализовать то, что я хочу сделать.

Я пытаюсь разработать, как другой процесс будет знать о событии, запускаемом, таким образом, это сможет сделать задачи, которые это должно сделать, я не понимаю, как один процесс, который является отдельным от другого, может сказать то, что состояния события находятся в том, тем более, что это должно действовать, как только событие изменило состояние.

Спасибо за любую справку

Править:

Я могу только использовать Создать/Установить/Открыть методы для событий, извините для того, чтобы не упоминать это ранее.

Кроме того, я создаю новый поток в процессе, который позволяет пользователю взаимодействовать с приложением при прислушивании к близкому событию.

Создайте поток:

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);
            }

Открытие на, когда B закрывается:

    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 в b (В 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);
            }

Установка события к сообщенному, когда B закрывается:

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

Поскольку Вы видите, когда Событие сообщено, приложение A установлено закрыться. То, когда я запускаю и приложение и близко обрабатываю B, обрабатываю A, не замечает измененный сигнал и не закрывается.

Редактирование 2:

После использования GetLastError (); я смог определить, что дескриптор к OpenEvent был ПУСТЫМ, данная ошибка

ERROR_FILE_NOT_FOUND - 2: система не может найти файл указанным

Мой метод создания события и чтения его неправильный, я удостоверился, что включал префикс Global\.

6
задан Jamie Keeling 27 April 2010 в 17:21
поделиться

2 ответа

Семафоры хороши тем, что они единолично заботятся о синхронизации глубины очереди между двумя процессами. Поскольку вместо этого вы ограничены использованием объектов Event, я бы предложил использовать межпроцессные сообщения вместо очереди или очереди из одного, если хотите.

Процесс 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);
}

Процесс 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);
}

Если, как я предполагаю, вы действительно хотите иметь очередь длиной больше единицы, вы можете реализовать логику организации очередей в процессе b. Вы захотите сделать это в отдельном потоке по нескольким причинам. Реализация логики очереди зависит от вас. В зависимости от ваших потребностей в эффективности это может быть круговой массив, связанный список или ???.

// In process b's 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);
  }
}
4
ответ дан 17 December 2019 в 02:25
поделиться

Звуки например, вы могли бы захотеть использовать CreateSemaphore . Вы можете использовать семафор для представления количества элементов данных, доступных для обработки процессом b. Инициализируйте его до 0, когда элемент данных становится доступным, увеличивайте его с помощью ReleaseSemaphore . Затем в вашем процессе b вызовите WaitForSingleObject или один из его собратьев, который вернется только тогда, когда счетчик семафоров станет больше 0, после чего счетчик уменьшается.

Это не полное решение, потому что вам все еще нужно решать такие вещи, как, например, что делать, когда ваш общий буфер заполнен, но это должно помочь вам хорошо и по-настоящему начать.

2
ответ дан 17 December 2019 в 02:25
поделиться
Другие вопросы по тегам:

Похожие вопросы: