我正在编写以下代码来终止具有给定 PID 的进程:
int TerminateProcessInstance(DWORD dwPID)
{
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID);
if (!TerminateProcess(hProcess, 0))
{
cout << "Failed to initiate terminate process" << endl;
return -1;
}
else
{
// Now that the termination of process is initiated,
// how do I confirm the process is terminated before proceeding here
}
CloseHandle(hProcess);
return 0;
}
TerminateProcess API 文档提到使用 WaitForSingleObject 来确保进程已终止:
TerminateProcess 是异步的;它启动终止并立即返回。如果您需要确保进程已终止,请使用进程句柄调用 WaitForSingleObject 函数。
我应该像这样更新代码吗?
int TerminateProcessInstance(DWORD dwPID)
{
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID);
if (!TerminateProcess(hProcess, 0))
{
cout << "Failed to initiate terminate process" << endl;
return -1;
}
else
{
bool bStatus = WaitForSingleObject(hProcess, 60000);
if(bStatus == WAIT_TIMEOUT)
{
cout << "Failed to terminate process" << endl;
return -1;
}
}
CloseHandle(hProcess);
return 0;
}
我的另一个问题是,如果在我调用 WaitForSingleObject 之前 TerminateProcess 确实成功终止了进程,那么句柄 hProcess 的状态将是什么?
这种情况下 WaitForSingleObject 会失败吗?
在进程句柄上调用(对象)wait 函数 是一项定义明确的操作,可以确定进程是否已终止。
这是易于遵循的建议。为了理解为什么这是真的,我们需要涵盖几个概念并在此过程中引入支持术语。
从根本上来说,进程是一个保存资源的容器。代表进程的object是数据。数据不执行。
执行单元是线程。每个线程都属于一个进程。当我们通俗地说“进程执行”时,我们的意思是“进程拥有的一个或多个线程有资格运行。”
TerminateProcess
的调用会遍历进程对象中存储的所有线程,并依次终止每个线程。进程对象本身保持活动状态。
随着核心原语的粗略描述,上一段留下了一个问题:如果
TerminateProcess
不销毁进程对象,谁会销毁,何时销毁?
(内核)对象生命周期由 对象管理器负责。它维护每个对象的引用计数,在将
HANDLE
分发给客户端时递增它,并在客户端通过调用 CloseHandle
放弃其(共享)所有权时递减它。
引用的对象仅在其最终的
HANDLE
被释放后才会被销毁。因此,对 OpenProcess
的成功调用至少会使进程对象保持活动状态,直到 HANDLE
被传递到 CloseHandle
中为止。
最后一部分围绕同步 API。每当对象收到信号或超时到期(以先发生者为准)时,等待函数(例如
WaitForSingleObject
)就会返回。当进程出于自由意志或强制终止时,进程对象会转换到(并保持)有信号状态。
总结:
OpenProcess
可以让您控制流程对象的生命周期TerminateProcess
不会破坏进程对象由于以下几个原因,建议的代码仍然是错误的:
PROCESS_ALL_ACCESS
) 比它需要的 (PROCESS_TERMINATE | SYNCHRONIZE
)OpenProcess
WaitForSingleObject
的返回值强制转换为 bool
HANDLE
更好的实现应该是这样的:
int TerminateProcessInstance(DWORD dwPID) {
HANDLE hProcess = OpenProcess(PROCESS_TERMINATE | SYNCHRONIZE, FALSE, dwPID);
if (hProcess == NULL) return -1;
if (!TerminateProcess(hProcess, 0)) {
cout << "Failed to initiate terminate process" << endl;
CloseHandle(hProcess);
return -1;
}
DWORD res = WaitForSingleObject(hProcess, 60000);
if(res != WAIT_OBJECT_0) {
cout << "Process didn't terminate within timeout" << endl;
CloseHandle(hProcess);
return -1;
}
CloseHandle(hProcess);
return 0;
}
使用 Windows 实现库 将使此代码更短、更具可读性、可维护性和健壮性。