在进程间使用事件对象
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】:您的代码需要检查和处理错误。如果CreateEvent
和OpenEvent
失败,它们都将返回NULL
,在这种情况下,您需要使用GetLastError
检查错误。
还应根据 MSDN 文档检查您对 WaitForSingleObject
和 SetEvent
的调用。
在父进程中你需要做的事情的顺序是:
创建事件 启动子进程 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
也许您需要创建一个适当的安全描述符?
【讨论】:
以上是关于在进程间使用事件对象的主要内容,如果未能解决你的问题,请参考以下文章