Понимание WaitForSingleObject и WaitForMultipleObject

У меня есть служба Windows, где я получаю http-запросы и запускаю процесс, который может выполняться более часа. Мне нужно получать уведомления в основном сервисе, когда процесс заканчивается. И когда сервис заканчивается, мне нужно завершить все дочерние процессы. Я понимаю, что если я сделаю wait для одного объекта, он будет зависать в службе Windows до тех пор, пока процесс не будет завершен, и дальнейшие запросы http не будут приниматься? Я делаю следующее пока что работает, но это не правильный подход.

if(CreateProcess( TEXT(EXEPATH),
procArguments,
NULL,
NULL,
FALSE,
0,
NULL,
NULL,
&si,
&pi )
)
{
processHandles[processCount] = pi.hProcess;
processStreams[processCount] = eventId.c_str();
processCount++;
}

На остановке службы я делаю это

for(int index=0;index<10;index++){
g_pAppLog->Log("Stop Process for processStreams[%d] %s\n",index,processStreams[index].c_str());

int terminationResult = TerminateProcess(processHandles[index],1);

}

1

Решение

Функции WaitForSingleObjectEx а также WaitForMultipleObjectsEx позволяют указать время ожидания, чтобы функция не зависала вечно.

Таким образом, вы можете вызывать функцию в цикле, проверяя, действительно ли процесс завершился или это просто истечение времени ожидания.

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

Итак, подытоживая, вы можете либо:

  1. Запустите цикл, который:
    1. принимает запрос;
    2. порождает процесс;
    3. проверяет, завершен ли какой-либо ранее созданный процесс (без блокировки);
  2. Создайте приложение с двумя потоками, один поток принимает запросы, а другой вызывает WaitForMultipleObjectsEx в цикле, и, возможно, обработки дочернего завершения.
0

Другие решения

В вашем основном сервисе вы должны создать поток, чтобы сделать это, чтобы основной поток все еще работал. В этом потоке вы должны использовать WaitforMultipleObjects, чтобы дождаться завершения всех дочерних процессов, как только процесс завершится, соответствующий код будет выполнен.

Пожалуйста, проверьте MSDN для деталей

0

Ожидайте в другом потоке, чем тот, который обрабатывает запросы SCM. использование CreateEvent() создать ожидаемое событие ручного сброса, а затем использовать ожидающий поток WaitForMultipleObjects() ждать и события, и дочернего процесса одновременно. WaitForMultipleObjects() скажу вам, какой из них сигнализируется первым. Когда служба останавливается, сообщите о событии с помощью SetEvent(), Когда дочерний процесс завершается, его дескриптор будет сигнализирован. Если событие получает сигнал первым, ожидающий поток может вызвать TerminateProcess() на дочернем процессе.

0