在进程间使用事件对象

Posted

技术标签:

【中文标题】在进程间使用事件对象【英文标题】:Using event object in inter-process 【发布时间】:2010-11-09 05:06:23 【问题描述】:

我正在尝试在 win32 环境中使用事件对象来同步两个进程。下面是两个程序的简化代码。

// process1
int main()

    HANDLE h = CreateEvent(NULL, FALSE, FALSE, TEXT("Hello"));
    WaitForSingleObject(h, INFINITE);
//  RunProcess(L"process2.exe", L"");


// process2
int main()

    HANDLE h = OpenEvent(EVENT_MODIFY_STATE, FALSE, TEXT("Hello"));
    SetEvent(h);    

这很简单,当两个进程独立启动时效果很好。但是,当进程 1 将进程 2 作为子进程启动时(在上面的代码中对此进行了注释),它不起作用 - SetEvent 调用失败。这个问题的原因和解决方法是什么?

【问题讨论】:

【参考方案1】:

您的代码需要检查和处理错误。如果CreateEventOpenEvent 失败,它们都将返回NULL,在这种情况下,您需要使用GetLastError 检查错误。

还应根据 MSDN 文档检查您对 WaitForSingleObjectSetEvent 的调用。

在父进程中你需要做的事情的顺序是:

创建事件 启动子进程 WaitForSingleObject。

否则你会遇到@Mark Tolonen 提出的问题。

最好在等待时设置一个超时,以处理子进程无法启动、意外退出或挂起的情况。

如果您打算使用这种父/子关系,另一种方法是允许继承事件句柄。然后事件不需要命名,并且没有其他人可以在对您的应用程序的 DoS 攻击中“蹲”在它上面。您可以将句柄值作为命令行参数传递给子项。您可以使用 eventAttributes 参数上的 bInheritHandle 字段到 CreateEvent

一个布尔值,指定是否 返回的句柄在什么时候被继承 一个新的进程被创建。如果这 成员为TRUE,新流程 继承句柄。

【讨论】:

感谢您的详细解答!这个问题已经神奇地解决了——它最终在今天有效,无需修改代码。 :( 虽然我觉得我应该写一些异常处理代码,你帮了我很多。【参考方案2】:

你确定吗?如前所述,如果 process1 在当前位置创建 process2,它将永远不会创建 process2,因为它将永远等待事件被触发。先创建process2,然后等待事件设置完毕。

【讨论】:

啊,这是我的错误 - 原始代码更复杂,我在简化代码时犯了一个错误。 :( 如您所说,注释的代码应移至 WaitForSingleObject 上方。 只要问题不变,这个答案简直是对的:-)【参考方案3】:

你有一个 NULL 安全描述符,文档说它不能允许子进程继承句柄,特别是:

If this parameter is NULL, the handle cannot be inherited by child processes

也许您需要创建一个适当的安全描述符?

【讨论】:

以上是关于在进程间使用事件对象的主要内容,如果未能解决你的问题,请参考以下文章

事件驱动的进程间通信 (IPC)

事件函数SetEventPulseEvent与WaitForSingleObject详解

POSIX 进程间同步

OpenHarmony-内核对象事件之源码详解

Guava ---- EventBus事件驱动模型

面试题目二