具有WaitForSingleObject性能降级的CreateProcess

时间:2009-10-29 22:09:23

标签: performance winapi process

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

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

我自己曾多次使用过它。但最近我发现,当它启动一个带有多媒体播放的程序时,这个调用的性能比从一般文件管理器(Windows XP)执行的相同进程要差。我的(父)进程的CPU消耗是可以的,但是在播放片段时会出现意外的停顿。

我对以下内容做了一些改动:

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

它有所帮助。现在,子进程播放片段没有问题。 那么第一个片段出了什么问题呢?它是在某个地方记录的吗?正如我从测试中看到的那样,第二次“等待”比第一次更“放松”,但是第一种“至少不正式地吃CPU”

1 个答案:

答案 0 :(得分:3)

如果此代码在UI线程上运行,则会导致(直接或间接)向窗口发送消息的其他进程出现性能问题,因为在等待时不运行消息循环儿童过程。 Sleep()WaitForSingleObject()都不会处理邮件。

Windows资源管理器(文件管理器)不会遇到此问题,因为它:

  1. 不会根据用户的请求对其启动的进程保持打开句柄(我认为这更有可能,因为资源管理器既不需要知道进程退出的时间还是退出代码),或者
  2. 不等待任何打开的进程句柄,它可以保留其子级,重要的是
  3. 始终确保在等待句柄时运行消息循环。这在使用COM的任何进程中都非常重要,而Explorer大量使用它。
  4. 您可以调用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;
        }
    }