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

时间:2018-09-24 08:05:15

标签: c++ multithreading winapi

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

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

那些句柄仅在其进程空间上有效吗,如何使用已存储的所有句柄从另一个进程中挂起/恢复线程或进程?

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

另一个问题是;如何从主进程(也创建该ProcessClass)获取由我的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;
}

在ManageProcess函数中,该函数与ProcessClass和以下结构定义在同一个lib项目中:

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;

2 个答案:

答案 0 :(得分:2)

  

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

这是因为您正在将进程句柄(pi.hProcess)传递给ResumeThread()。您无法使用ResumeThread()恢复过程。顾名思义,您需要为其传递一个 thread 句柄(pi.hThread)。

  

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

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

Creating Processes

  

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

     

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

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

答案 1 :(得分:-2)

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

我只是以一种在IO选择器,任务队列上唤醒线程(通过IOLoop,Dispatcher,Executor,Actor等的方式)构建应用程序的方式,仅唤醒和有工作要做时做些什么。