【问题标题】:CreateProcess with WaitForSingleObject performance degradationCreateProcess 与 WaitForSingleObject 性能下降
【发布时间】:2009-10-29 22:09:23
【问题描述】:

可能每个人都知道运行程序并等待程序结束的代码:

   CreateProcess(...
   WaitForSingleObject(Process.hProcess, INFINITE

我自己用了好几次。但是最近我发现,当它启动一个带有多媒体播放的程序时,这个调用的性能比从通用文件管理器(Windows XP)执行的相同进程要差。我的(父)进程的 CPU 消耗没关系,但是在播放片段时,会有意想不到的小停顿。

我对类似的东西做了一点改动:

CreateProcess ...
do {
    Sleep(100);
    Res = WaitForSingleObject(Process.hProcess, 10);
} while (Res == WAIT_TIMEOUT);

它有帮助。现在子进程播放片段没有问题。 那么第一个片段有什么问题,它是否记录在某个地方?正如我从测试中看到的,第二个“等待”比第一个更“放松”,但第一个至少在形式上不会占用 CPU

【问题讨论】:

    标签: performance winapi process


    【解决方案1】:

    如果此代码在 UI 线程上运行,您将导致其他进程(直接或间接)向您的窗口发送消息的性能问题,因为您在等待子进程。 Sleep()WaitForSingleObject() 都不会处理消息。

    Windows Explorer(文件管理器)不会遇到这个问题,因为它:

    1. 不为它应用户请求启动的进程保留一个打开的句柄(我认为这更有可能,因为 Explorer 不需要知道进程何时退出或其退出代码),或者
    2. 不等待任何可能对其子进程保留的打开进程句柄,重要的是
    3. 始终确保在等待句柄时运行消息循环。这在任何使用 COM(Explorer 大量使用)的进程中都非常重要。

    您可以调用MsgWaitForMultipleObjects(),而不是调用WaitForSingleObject()。如果您为 dwWaitMask 参数指定 QS_ALLINPUT,则 MsgWaitForMultipleObjects 将在您的事件发出信号或线程的消息队列中有输入时返回。如果因为消息可用而返回 MsgWaitForMultipleObjects(),您可以对其进行处理并继续等待:

    MSG msg;
    DWORD reason = WAIT_TIMEOUT;
    while (WAIT_OBJECT_0 != reason) {
        reason = MsgWaitForMultipleObjects(1, &hChildProcess, FALSE, INFINITE, QS_ALLINPUT);
        switch (reason) {
        case WAIT_OBJECT_0:
            // Your child process is finished.
            break;
        case (WAIT_OBJECT_0 + 1):
            // A message is available in the message queue.
            if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
                // Note that if your main message loop does additional processing
                // (such as calling IsDialogMessage() for modeless dialogs)
                // you will want to do those things here, too.
            }
            break;
        }
    }
    

    【讨论】:

    • 你看错了一面。显然,如果父进程被阻塞等待,子进程的性能会更差。确实是WTF。
    • 此答案中的小错误:MsgWaitForMultipleObjects() 指向的链接实际上指向 Sleep() 函数的 MSDN 文档。在某种程度上有点好笑。 ;-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-25
    相关资源
    最近更新 更多