Как реализовано ожидание в C?

#c #concurrency #signals #wait

Вопрос:

Когда я создаю два дочерних процесса, я не могу использовать SIGCHLD, чтобы определить, завершились ли оба дочерних процесса, так как после доставки сигнала будущие сигналы того же типа отбрасываются. Когда я получаю сигнал SIGCHLD и обрабатываю этот сигнал, я не могу быть уверен, означает ли это, что оба дочерних процесса завершили работу и отправили сигнал SIGCHLD или только один из них завершился. Другими словами, сигналы не ставятся в очередь. Однако с помощью функции wait(), если у меня есть два дочерних процесса, я могу дважды вызвать wait (), чтобы использовать оба дочерних процесса, и мне интересно, как это реализовано под капотом. Похоже, он не использует SIGCHLD, так как сигналы не ставятся в очередь. Итак, как он может обрабатывать завершенные дочерние процессы один за другим?

Ответ №1:

В подобных случаях вместо этого вы бы вызывали waitpid() с WNOHANG флагом в цикле, пока он не вернет 0, чтобы указать, что ни один из указанных процессов не изменил состояние (или -1, чтобы указать на ошибку).

 int status;
pid_t p;
while ((p = waitpid(-1, amp;status, WNOHANG)) > 0) {
    // Inspect status and do whatever
}
 

Что касается того, как они работают под капотом? Ядро сохраняет запущенные, но еще не дождавшиеся процессы в своем списке процессов (так называемые зомби-процессы). wait() просто возвращает статус одного из вышедших дочерних элементов вызывающего абонента или блокирует его до тех пор, пока не появится один (или ошибка), после чего процесс вызова планируется запустить снова.

Комментарии:

1. Когда родительский процесс приходит сюда, но дочерние процессы еще не завершены, кажется, что он не будет ждать завершения дочерних процессов?

2. wait() блоки для запущенных детей, если нет ожидающих завершения. waitpid() может быть, а может и не быть, в зависимости от флагов.

3. @Xiaohuolong — вы можете поместить приведенный выше пакет кода в свой обработчик SIGCHLD. В некоторых программах (особенно с потоками) обработчики сигналов немного неудобны, поэтому вам, возможно, придется устанавливать в них флаги или выпускать семафоры.