我有以下代码示例:
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
函数的理解错过了一些东西。
答案 0 :(得分:6)
我在Windows 10上尝试了您的代码,SysInternals Process Monitor显示了以下内容:
如您所见,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()