WindowsAPI工作Objects:不要传给孙子
Windows API Job Objects: Don't pass on to grandchildren
我有一个 Windows 命令行应用程序 child.exe
,我想为其创建一个包装器 parent.exe
。我通过使用 CreateProcess
:
从 parent 生成 child 来做到这一点
int wmain(int argc, WCHAR *argv[]) {
STARTUPINFO startupInfo = createStartupInfo();
PROCESS_INFORMATION processInfo = {0};
if(CreateProcessW(
L"C:\child.exe", NULL, NULL, NULL, FALSE,
CREATE_NEW_CONSOLE, NULL, NULL, &startupInfo, &processInfo
)) {
WaitForSingleObject(processInfo.hProcess, INFINITE);
CloseHandle(processInfo.hThread);
CloseHandle(processInfo.hProcess);
return 0;
} else {
return -1;
}
}
STARTUPINFO createStartupInfo() {
// Create and return a STARTUPINFO structure...
}
我现在希望 child 进程在 parent 进程关闭时终止。在 another question 之后,我正在使用 Job Objects 来这样做:
// Create and initialise the job object:
HANDLE ghJob = CreateJobObject(NULL, NULL);
if (ghJob == NULL) { /* Error handling... */ }
else {
JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli = { 0 };
// Configure all child processes associated with the
// job to terminate when the parent closes:
jeli.BasicLimitInformation.LimitFlags =
JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
if (! SetInformationJobObject(
ghJob, JobObjectExtendedLimitInformation, &jeli, sizeof(jeli)
)) { /* Error handling... */ }
}
然后我通过 AssignProcessToJobObject
:
将创建的 child 进程分配给此作业
if(CreateProcessW(...)) {
AssignProcessToJobObject(ghJob, processInfo.hProcess));
WaitForSingleObject(processInfo.hProcess, INFINITE);
...
} ...
这行得通:因为新创建的进程被分配给 JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE
的作业,所以当 parent 进程出于任何原因关闭时,child 进程自动终止。
但这是我的问题:我无法控制 child.exe
。它产生自己的 sub-processes(比如 grandchild.exe
),所以我们有:
parent.exe -> child.exe -> grandchild.exe
不幸的是,当我如上所述将作业 object 分配给 child.exe
时,这个 "spawning of grandchild.exe
" 失败了。我相信这是因为 grandchild.exe
继承了我的工作定义,但 child.exe
试图将其自己的工作定义应用于 grandchild.exe
但失败了,因为在 Windows 7 上,工作可能只与一份工作。 docs for AssignProcessToJobObject
表示如果希望创建不从 parent 继承作业的进程,则必须在调用 CreateProcess
时使用 CREATE_BREAKAWAY_FROM_JOB
标志。但问题是对 CreateProcess
的调用发生在 child.exe
内部,我无法访问它。
谁能想出一个解决方案,允许 child.exe
自由生成自己的(大)child 进程,同时让我可以终止 child.exe
parent.exe
何时关闭?
您只需要在作业上设置 JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK
标志。此标志可防止子进程自动分配给作业。
使用SetInformationJobObject
函数和JobObjectExtendedLimitInformation
选项。该标志在 MyExtendedLimitInformation.BasicLimitInformation.LimitFlags
成员中设置。
我有一个 Windows 命令行应用程序 child.exe
,我想为其创建一个包装器 parent.exe
。我通过使用 CreateProcess
:
int wmain(int argc, WCHAR *argv[]) {
STARTUPINFO startupInfo = createStartupInfo();
PROCESS_INFORMATION processInfo = {0};
if(CreateProcessW(
L"C:\child.exe", NULL, NULL, NULL, FALSE,
CREATE_NEW_CONSOLE, NULL, NULL, &startupInfo, &processInfo
)) {
WaitForSingleObject(processInfo.hProcess, INFINITE);
CloseHandle(processInfo.hThread);
CloseHandle(processInfo.hProcess);
return 0;
} else {
return -1;
}
}
STARTUPINFO createStartupInfo() {
// Create and return a STARTUPINFO structure...
}
我现在希望 child 进程在 parent 进程关闭时终止。在 another question 之后,我正在使用 Job Objects 来这样做:
// Create and initialise the job object:
HANDLE ghJob = CreateJobObject(NULL, NULL);
if (ghJob == NULL) { /* Error handling... */ }
else {
JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli = { 0 };
// Configure all child processes associated with the
// job to terminate when the parent closes:
jeli.BasicLimitInformation.LimitFlags =
JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
if (! SetInformationJobObject(
ghJob, JobObjectExtendedLimitInformation, &jeli, sizeof(jeli)
)) { /* Error handling... */ }
}
然后我通过 AssignProcessToJobObject
:
if(CreateProcessW(...)) {
AssignProcessToJobObject(ghJob, processInfo.hProcess));
WaitForSingleObject(processInfo.hProcess, INFINITE);
...
} ...
这行得通:因为新创建的进程被分配给 JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE
的作业,所以当 parent 进程出于任何原因关闭时,child 进程自动终止。
但这是我的问题:我无法控制 child.exe
。它产生自己的 sub-processes(比如 grandchild.exe
),所以我们有:
parent.exe -> child.exe -> grandchild.exe
不幸的是,当我如上所述将作业 object 分配给 child.exe
时,这个 "spawning of grandchild.exe
" 失败了。我相信这是因为 grandchild.exe
继承了我的工作定义,但 child.exe
试图将其自己的工作定义应用于 grandchild.exe
但失败了,因为在 Windows 7 上,工作可能只与一份工作。 docs for AssignProcessToJobObject
表示如果希望创建不从 parent 继承作业的进程,则必须在调用 CreateProcess
时使用 CREATE_BREAKAWAY_FROM_JOB
标志。但问题是对 CreateProcess
的调用发生在 child.exe
内部,我无法访问它。
谁能想出一个解决方案,允许 child.exe
自由生成自己的(大)child 进程,同时让我可以终止 child.exe
parent.exe
何时关闭?
您只需要在作业上设置 JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK
标志。此标志可防止子进程自动分配给作业。
使用SetInformationJobObject
函数和JobObjectExtendedLimitInformation
选项。该标志在 MyExtendedLimitInformation.BasicLimitInformation.LimitFlags
成员中设置。