Введение
У меня многопоточное приложение, работающее через Boost.Asio. Для всего приложения существует только один boost::asio::io_service
, и все вещи выполняются внутри него группой потоков. Иногда необходимо создавать дочерние процессы с использованием fork и exec. Когда ребенок заканчивается, мне нужно сделать waitpid на нем, чтобы проверить код выхода a, чтобы собрать зомби. Недавно я добавил boost::asio::signal_set
, но столкнулся с проблемой в древних системах с ядрами linux-2.4. * (Которые, к сожалению, все еще используются некоторыми клиентами). В старых ядрах Linux потоки фактически являются особыми случаями процессов, и поэтому, если ребенок был порожден одним потоком, другой поток не может дождаться его, используя семейство системных вызовов waitpid
. Asio signal_set отправляет обработчик сигналов на io_service
, и любой поток, выполняющий эту службу, может запускать этот обработчик, что неуместно для моего случая. Поэтому я решил обрабатывать сигналы по старому хорошему сигналу/сигмату - все потоки имеют тот же обработчик, который вызывает waitpid
. Итак, есть еще одна проблема:
Проблема
Когда сигнал улавливается обработчиком, и процесс успешно выполняется, как я могу "отправить" это в мой io_service
из обработчика? Как мне кажется, очевидный метод io_service::post()
невозможен, потому что он может зайти в тупик во внутренних мьютексах io_service
, если сигнал приходит в неправильное время. Единственное, что мне пришло в голову, это использовать какую-либо трубку или сокет-пару для записи уведомлений там и async_wait
на другом конце, поскольку иногда это делается для обработки сигналов в циклах событий poll()
.
Есть ли лучшие решения?