Windows: использование событий для синхронизации общей памяти - PullRequest
0 голосов
/ 12 января 2019

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

Процесс A: Сигнальное событие для процесса B

Процесс A: дождитесь ответа процесса B

Процесс B: получение события, выполнение операции с памятью

Процесс B: Сигнальное событие для процесса A

Процесс B: дождитесь ответа процесса A

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

Вот как я создаю событие (оно создается в ядре и совместно используется драйвером и программой пользовательского режима):

ZwCreateEvent(&hEvent, EVENT_ALL_ACCESS, &oa, SynchronizationEvent, FALSE);

Вот как я могу открыть событие в программе пользовательского режима:

HANDLE ghWriteEvent = OpenEvent(EVENT_MODIFY_STATE, FALSE, TEXT("Global\\WriteEvent01"));

Вот как я сейчас сигнализирую о событии в режиме пользователя:

SetEvent(ghWriteEvent);
ResetEvent(ghWriteEvent);
WaitForSingleObject(ghWriteEvent, INFINITE);

Вот как я сигнализирую четность в ядре:

KeSetEvent(kEvent, LOW_REALTIME_PRIORITY, FALSE);
KeResetEvent(kEvent);
KeWaitForSingleObject(kEvent, Executive, KernelMode, TRUE, NULL);

Я использую SetEvent (), чтобы сигнализировать другой процесс, а затем ResetEvent (), чтобы WaitForSingleObject () успешно выполнялся только тогда, когда он получает сигнал от другого процесса.

Это правильный способ синхронизации двух процессов? Я не уверен, так как это работает 90% времени, но иногда это не так.

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

Есть очевидная ошибка, которую я упустил из виду? Спасибо.

1 Ответ

0 голосов
/ 13 января 2019

Как отметили Джонатан Поттер, RbMm и Майкл, использование только одного события для синхронизации ненадежно, поскольку вы должны использовать «PulseEvent».

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

...