从不同进程中的另一个线程挂起/恢复线程或进程

Suspend/Resume a thread or process from another Thread in different process

本文关键字:进程 线程 挂起 恢复 另一个      更新时间:2023-10-16

在我的一个项目中,我从我的主项目创建多个进程(这是我开发的子项目(作为CREATE_SUSPENDED并将它们的句柄存储在全局数组中;当我想使用ResumeThread函数恢复它时,我得到ERROR_INVALID_HANDLE错误代码。

MSDN 指定线程必须具有THREAD_SUSPEND_RESUME访问权限,但我找不到如何设置它。

这些句柄是否仅在其进程空间上有效,以及如何使用我存储的所有句柄从另一个进程挂起/恢复线程或进程?

注意:我知道同步对象在这里可能有用处,但这是唯一的方法吗?

另一个问题是;如何从主进程获取我的 ProcessClass 创建的线程的句柄,主进程也创建了该 ProcessClass?

这是代码的一部分

进程类

void ProcessClass::Start(){       
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&pi, sizeof(pi));
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
BOOL createdProc = CreateProcess(NULL, 
ProcessExeDir, 
NULL, 
NULL, 
TRUE, 
CREATE_NEW_CONSOLE | CREATE_SUSPENDED
, NULL, 
NULL, 
&si, 
&pi); 
if (createdProc == FALSE)
{
UINT32 errorCode = GetLastError();        
}
else
{
DWORD affinity;
affinity = 0x000000010 << (5);
SetProcessAffinityMask(pi.hProcess, affinity);
ProcessHandler = pi.hProcess;
ProcessInfoPtr->ProcHandle = ProcessHandler;
// I can need this handle
// CloseHandle(pi.hThread);
}
}
// ProcessInPtr is defines as ProcessInfoStc* in the header
ProcessInfoStc* ProcessClass::GetProcessInfoPtr() {
return ProcessInfoPtr;
}

在主项目中:

int main() {
// this is declared as ManageProcesses(const ProcessInfoStcPtr& processes)
ManageProcesses(ProcessInfoArray);
return 0;
}

在与ProcessClass和以下结构定义位于同一lib项目中的ManageProcess函数中:

ProcessClass processObj = new ProcessClass();
processObj->Start();
...
HANDLE pHandle = processObj->GetProcessInfoPtr()->ProcHandle;
//! pHandle is is same with the created process handle as I debug
ResumeThread(pHandle); 
DWORD error = GetLastError(); // RETURNS INVALID HANDLE

并且存储过程的结构也在主流程中

ProcessInfoStc {
HANDLE ProcHandle ,
DWORD ProcId..
}
ProcessInfoStc ProcessInfoArray[10] = {
{
0,0...
},...
}
typedef ProcessInfoStc* ProcessInfoStcPtr;

在我的一个项目中,我从我的主项目创建多个进程(这是我开发的子项目(作为CREATE_SUSPENDED,并将它们的句柄存储在全局数组中,但是; 当我想使用ResumeThread函数恢复它时,我得到ERROR_INVALID_HANDLE错误代码。

这是因为您正在将进程句柄 (pi.hProcess( 传递给ResumeThread()。 不能使用ResumeThread()恢复进程。 顾名思义,您需要向它传递一个线程句柄(pi.hThread(。

MSDN 指定线程必须具有THREAD_SUSPEND_RESUME访问权限,但我找不到如何设置它。

根据文档,您已经拥有它:

创建流程

线程和进程句柄是使用完全访问权限创建的,但如果指定安全描述符,则可以限制访问。

如何从主进程中获取我的ProcessClass创建的线程的句柄,该线程也创建了该ProcessClass

您当前未将线程句柄存储在任何地方,无法检索它。 更新ProcessInfoStc结构以存储CreateProcess()返回的两个HANDLE。 并且不要忘记在使用完它们后关闭它们。

我建议不要使用操作系统或线程库低级API停止/恢复线程,除非您正在编写线程调度算法(但随后您的代码应驻留在内核中(。在现代操作系统和正确编写的多线程应用程序线程中,处于等待状态的多线程线程几乎不消耗任何资源,因此确实没有理由在那里进行干预。这就是为什么你现在不太可能在实际代码示例中看到thread.suspend()thread.resume()的原因。

我只会按照线程在 IO 选择器、任务队列上轮询的方式(通过 IOLoop、调度程序、执行器、执行器等的抽象(构建一个应用程序,并且只有在有工作要做时才唤醒并做某事。