每个人都可能知道运行程序并等待它结束的代码:
CreateProcess(...
WaitForSingleObject(Process.hProcess, INFINITE
我自己曾多次使用过它。但最近我发现,当它启动一个带有多媒体播放的程序时,这个调用的性能比从一般文件管理器(Windows XP)执行的相同进程要差。我的(父)进程的CPU消耗是可以的,但是在播放片段时会出现意外的停顿。
我对以下内容做了一些改动:
CreateProcess ...
do {
Sleep(100);
Res = WaitForSingleObject(Process.hProcess, 10);
} while (Res == WAIT_TIMEOUT);
它有所帮助。现在,子进程播放片段没有问题。 那么第一个片段出了什么问题呢?它是在某个地方记录的吗?正如我从测试中看到的那样,第二次“等待”比第一次更“放松”,但是第一种“至少不正式地吃CPU”
答案 0 :(得分:3)
如果此代码在UI线程上运行,则会导致(直接或间接)向窗口发送消息的其他进程出现性能问题,因为在等待时不运行消息循环儿童过程。 Sleep()和WaitForSingleObject()都不会处理邮件。
Windows资源管理器(文件管理器)不会遇到此问题,因为它:
您可以调用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;
}
}