Замена SIGCHLD для Windows

Я хотел бы иметь функциональность SIGCHLD в Windows (т.е. уведомлять родительский процесс, когда умирает ребенок). Я знаю, что в Windows API нет эквивалента SIGCHLD, но я хотел бы знать, каков общий метод для реализации этого в Windows. Я уверен, что это проблема, с которой разработчики Windows сталкиваются довольно часто.

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

Примечание. Мое приложение является однопоточным, и я хотел бы сохранить его таким, если это возможно. Приложение имеет неблокирующий цикл событий (используя select()).


person Matt Fichman    schedule 09.02.2012    source источник


Ответы (2)


Я не знаю, лучший ли это способ, но это определенно способ.

Я предполагаю, что вы создаете процесс с помощью CreateProcess. Это возвращает структуру PROCESS_INFORMATION, содержащую член hProcess. Это дескриптор созданного вами дочернего процесса.

Отсюда вы можете ждать этого дескриптора с помощью WaitOnSingleObject, который будет блокироваться до тех пор, пока данный дескриптор не будет сигнализирован (хотя требуется тайм-аут, если вы предпочитаете делать это неблокирующим — это ближайший эквивалент select, который вы получите ).

Если вы идете по многопоточному маршруту, вы можете подождать в отдельном потоке, а затем, когда WaitOnSingleObject пройдет, вы можете соответствующим образом уведомить рабочий поток в родительском процессе.

В однопоточном стиле вы будете просто опрашивать дескриптор в цикле, если используете семантику в стиле select.

Если у вас есть несколько дочерних объектов для ожидания (учитывая, что вы уже используете select), вы можете рассмотреть WaitForMultipleObjects - если это подходящая модель для вашего кода.

person Chris J    schedule 09.02.2012
comment
Этот маршрут менее трудоемок, чем мой ответ, и если он подходит, если вы заботитесь (и должны ждать) только об одном дочернем элементе, но если вам нужна информация о внуках или если дочерний процесс не ждет своих дочерних элементов, вам нужен объект задания . - person Anders; 10.02.2012
comment
Я согласен: это способ дождаться завершения ваших детей. Документировано миллион раз в MSDN. Не забудьте ::CloseHandle(), возвращаемый ::CreateProcess(), независимо от того, ждете ли вы этого или нет! Закрытие дескриптора не влияет на дочерний процесс. - person kkm; 10.02.2012
comment
Есть ли способ использовать порты завершения для этого? Мне нужно ждать потенциально более 64 детей. - person Matt Fichman; 13.02.2012

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

Используйте JobObjectAssociateCompletionPortInformation и поймать JOB_OBJECT_MSG_ABNORMAL_EXIT_PROCESS или JOB_OBJECT_MSG_EXIT_PROCESS.

person Anders    schedule 09.02.2012
comment
Поскольку select не является хорошей заменой сигналов, и ваш метод не требует от меня создания потока для каждого процесса, я думаю, что ваш метод ближе всего к тому, что можно получить для SIGCHLD в Windows, спасибо - person dashesy; 12.02.2013