【问题标题】:Windows: Using events for shared memory synchronizationWindows:使用事件进行共享内存同步
【发布时间】: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 个事件对象 AB 。一个做 - 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


【解决方案1】:

正如 Jonathan Potter、RbMm 和 Michael 指出的那样,仅使用一个事件来同步是不可靠的,因为您必须使用“PulseEvent”。

我的问题的解决方案是使用两个事件。一种用于发出内核模式已完成的信号,另一种用于发出用户模式已完成的信号。这解决了我的问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-12-31
    • 2012-04-27
    • 1970-01-01
    • 1970-01-01
    • 2013-09-01
    • 2016-05-25
    • 2019-10-25
    • 2014-04-08
    相关资源
    最近更新 更多