【发布时间】:2019-06-07 05:08:20
【问题描述】:
我正在使用事件来同步访问共享内存的两个进程。我想要达到的效果是这样的:
进程 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() 后将内容打印到控制台时,它可以工作。当我删除打印时,同步有时会失败。这让我相信同步调用之间需要有一定的延迟。
我是否忽略了一个明显的错误?谢谢。
【问题讨论】:
-
SetEvent + ResetEvent ==PulseEvent。你真的需要 2 个事件对象 A 和 B 。一个做 -write_data();set(A);wait(B)和另一个wait(A);process_data();set(B); -
SetEvent + ResetEvent != PulseEvent。 PulseEvent 不好。 PulseEvent 不可靠,不应使用。
-
对于您的工作,使用互斥锁可能会更好。这样你只需要一个互斥锁。不是两个事件。
-
好吧,这很有意义。似乎互斥锁是为我的确切问题而设计的。
-
SetEvent + ResetEvent 就是 PulseEvent。 PulseEvent 不好。 PulseEvent 不可靠,不应使用 - 正是因为您的代码 SetEvent + ResetEvent 不好且不可靠
标签: c windows winapi events driver