Вам действительно не нужно обрабатывать SIGCHLD
, если вы намереваетесь запустить дочерний процесс, сделайте что-нибудь, а затем дождитесь его завершения. В этом случае вы просто звоните waitpid
, когда будете готовы к синхронизации. Единственная вещь, для которой SIGCHLD
полезна, - это асинхронное уведомление о дочернем завершении, например, если у вас есть интерактивное (или долго работающий демон) приложение, которое порождает различных дочерних элементов и должно знать, когда они закончат работу. Тем не менее, SIGCHLD
действительно плохо / уродливо и для этой цели, так как, если вы используете библиотечный код, который создает дочерние процессы, вы можете перехватывать события для дочерних библиотек, завершающих работу, и мешать их обработке. Обработчики сигналов по своей природе глобальны для процессов и имеют дело с глобальным состоянием, которое обычно представляет собой A Bad Thing (tm).
Вот два лучших подхода, когда у вас есть дочерние процессы, которые будут завершаться асинхронно:
Подход 1 (select
/ poll
на основе событий): убедитесь, что у вас есть канал к / от каждого дочернего процесса, который вы создаете. Это может быть либо их stdin / stdout / stderr, либо просто дополнительный фиктивный fd. Когда дочерний процесс завершается, его конец канала будет закрыт, и ваш главный цикл обработки событий обнаружит активность этого дескриптора файла. Из того факта, что он закрылся, вы узнаете, что дочерний процесс умер, и позвоните waitpid
, чтобы пожать зомби.
Подход 2 (на основе потоков): для каждого создаваемого вами дочернего процесса также создайте поток, который немедленно вызовет waitpid
для pid дочернего процесса. Когда waitpid
вернется успешно, используйте ваши любимые примитивы синхронизации потоков, чтобы остальная часть программы знала, что дочерний процесс завершен, или просто позаботьтесь обо всем, что вам нужно сделать в этом потоке официантов, прежде чем он завершится.
Оба эти подхода являются модульными и дружественными к библиотеке (они избегают вмешательства в любые другие части вашего кода или библиотечного кода, которые могут использовать дочерние процессы).