Приостановить / возобновить поток или процесс из другого потока в другом процессе - PullRequest
0 голосов
/ 24 сентября 2018

В одном из моих проектов я создаю несколько процессов (которые являются подпроектами, которые я разработал) из моего основного проекта как CREATE_SUSPENDED и сохраняю их дескрипторы в глобальном массиве, но;когда я хочу возобновить его с функцией ResumeThread , я получаю ERROR_INVALID_HANDLE код ошибки.

В 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, которая находится в том же проекте lib с ProcessClass и следующими определениями структуры:

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 голосов
/ 24 сентября 2018

В одном из моих проектов я создаю несколько процессов (которые являются подпроектами, которые я разработал) из моего основного проекта как CREATE_SUSPENDED и храню их дескрипторы в глобальном массиве, но;когда я хочу возобновить его с помощью функции ResumeThread, я получаю ERROR_INVALID_HANDLE код ошибки.

Это потому, что вы передаете процесс дескриптор (pi.hProcess) в ResumeThread().Вы не можете возобновить процесс , используя ResumeThread().Как следует из его названия, вам нужно вместо него передать thread handle (pi.hThread).

MSDN указывает, что поток должен иметь право доступа THREAD_SUSPEND_RESUME, и яНе удалось найти способ его установки.

У вас уже есть, согласно документации:

Создание процессов

Дескрипторы потока и процесса создаются с полными правами доступа , хотя доступ можно ограничить, если указать дескрипторы безопасности.

как получить дескриптор потока, созданного моим ProcessClass, изОсновной процесс, который также создал это ProcessClass?

В настоящее время вы нигде не храните дескриптор потока, вы не можете его получить.Обновите структуру ProcessInfoStc, чтобы хранить оба HANDLE s, которые CreateProcess() возвращает.И не забудьте закрыть их оба, когда вы закончите с ними.

0 голосов
/ 24 сентября 2018

Я бы не рекомендовал останавливать / возобновлять потоки, используя низкоуровневые API-интерфейсы операционной системы или библиотеки потоков, если вы не пишете алгоритм планирования потоков (но тогда ваш код должен находиться в ядре).В современной ОС и правильно написанных многопоточных потоках приложений в состоянии ожидания практически не потребляют ресурсы, поэтому на самом деле не должно быть причин вмешиваться в них.По этой причине вы вряд ли увидите thread.suspend() и thread.resume() в практических примерах кода в наши дни.

Я бы просто создал приложение так, как опрашивали бы потоки (через абстракцию IOLoop, Dispatcher, Исполнитель, Актер и т. Д.) На селектор (ы) ввода-вывода, очереди (-ях) задач, и только просыпаются и делают что-то, когда есть работа, которую нужно сделать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...