为什么这两个不同的行为与WaitForSingleObject功能在CPP中

时间:2017-01-05 22:22:50

标签: c++ windows

我有以下代码示例:

select t.from_id, t2.from_id
from (select t.*, count(*) over (partition by from_id) as cnt
      from t
     ) t left join
     (select t.*, count(*) over (partition by from_id) as cnt
      from t
     ) t2
     on t.to_id = t2.to_id and t2.cnt = t.cnt
group by t.from_id, t2.from_id
having count(*) = count(t2.from_id);

当我尝试运行#include <iostream> #include <windows.h> #include <string> using namespace std; void main() { SHELLEXECUTEINFO ShExecInfo = { 0 }; ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO); ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS; ShExecInfo.hwnd = NULL; ShExecInfo.lpVerb = NULL; ShExecInfo.lpFile = "cmd.exe"; ShExecInfo.lpParameters = ""; ShExecInfo.lpDirectory = NULL; ShExecInfo.nShow = SW_SHOW; ShExecInfo.hInstApp = NULL; ShellExecuteEx(&ShExecInfo); WaitForSingleObject(ShExecInfo.hProcess, INFINITE); std::cout << "hi! Im done!"; system("pause"); } 的代码时,在关闭cmd.exe窗口之前,消息不会打印到屏幕上。

但是,当我尝试运行cmd.exe的代码时,会在计算器处理结束之前将消息打印到屏幕上。

为什么这两个可执行文件表现出不同的行为?

我认为我对calc.exe函数的理解错过了一些东西。

2 个答案:

答案 0 :(得分:6)

我在Windows 10上尝试了您的代码,SysInternals Process Monitor显示了以下内容:

image

如您所见,calc.exe产生一个新进程然后结束,从而满足等待。这就是你立即看到输出的原因。第二个过程是实际的计算器过程。就我而言,它位于这条路径上:

C:\Program Files\WindowsApps\Microsoft.WindowsCalculator_10.1612.3341.0_x64__8wekyb3d8bbwe\Calculator.exe

答案 1 :(得分:5)

正如marcinj解释的那样,calc.exe正在启动第二个流程,然后立即退出。您正在等待HANDLE calc.exe进程,以便在calc.exe退出时等待。

如果您想等到所有(大)子进程都结束,您需要将calc.exe进程包装在Job object内。

调用CreateJobObject(),将HANDLE进程的calc.exe传递给AssignProcessToJobObject(),然后等待来自作业对象的通知(只需等待作业本身不会工作,请参阅How do I wait until all processes in a job have exited?了解原因)。

calc.exe启动并启动的所有新流程等都将自动添加到同一作业中(除非他们明确要求不通过{{1}添加到作业中) } CREATE_BREAKAWAY_FROM_JOB的标志,但在这个例子中我们不要担心)。当作业通知您所有进程都已结束时,您可以停止等待进一步的通知。

例如:

CreateProcess()