在进程间使用事件对象

发布于 2024-09-30 22:32:07 字数 465 浏览 2 评论 0原文

我试图在 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 调用失败。这个问题的原因和解决方法是什么?

I'm trying to use event object in win32 environment to synchronize two processes. Below are the simplified code of two programs.

// 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);    
}

It's quite simple, and works well when two processes are launched independently. However it does not work when the process 1 launches process 2 as a child process (which is commented in the above code) - the SetEvent call fails. What is the reason and solution of this problem?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

_蜘蛛 2024-10-07 22:32:07

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

您对 WaitForSingleObjectSetEvent 的调用也应该根据 MSDN 文档进行检查。

在父进程中需要执行的操作顺序是:

  • CreateEvent
  • 启动子进程
  • WaitForSingleObject。

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

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

如果您打算使用这种父/子关系,另一种方法是允许继承事件句柄。然后,该事件不需要命名,其他人也无法在对您的应用程序进行 DoS 攻击时“抢占”该事件。您可以将句柄值作为命令行参数传递给子级。您可以使用 CreateEventeventAttributes 参数上的 bInheritHandle 字段来执行此操作。

一个布尔值,指定是否
当返回的句柄被继承时
创建一个新进程。如果这个
member为TRUE,新流程
继承句柄。

Your code needs to check and handle errors. Both CreateEvent and OpenEvent will return NULL if they fail, in that case you need to check the error using GetLastError.

Your calls to WaitForSingleObject and SetEvent should be checked per the MSDN docs as well.

The order in which you need to do things in the parent process is:

  • CreateEvent
  • Start child process
  • WaitForSingleObject.

Otherwise you will hit the problem called out by @Mark Tolonen.

It would also be best to have a timeout on your wait, to handle the case where the child process fails to start, exits unexpectedly, or hangs.

An alternative approach if you intend to use this parent/child relationship would be to allow inheritance of the event handle. Then the event does not need to be named, and nobody else can 'squat' on it in a DoS attack on your apps. You can pass the handle value to the child as a command-line parameter. You do this using the bInheritHandle field on the eventAttributes parameter to CreateEvent.

A Boolean value that specifies whether
the returned handle is inherited when
a new process is created. If this
member is TRUE, the new process
inherits the handle.

儭儭莪哋寶赑 2024-10-07 22:32:07

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

Are you sure? As written, if process1 creates process2 in the current location, it will never create process2 because it will wait forever for the event to be fired. Create process2 first, then wait for the event to be set.

铜锣湾横着走 2024-10-07 22:32:07

您有一个 NULL 安全描述符,文档说它不允许子进程继承句柄,具体来说:

如果此参数为 NULL,则子进程无法继承句柄

也许您需要创建正确的安全描述符?

You have a NULL security descriptor, which the documentation says cannot allow the handle to be inherited by children processes, specifically:

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

Maybe you need to create a proper security descriptor?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文