LINUX.ORG.RU

Задачка с потоками и sigchld.


0

0

Есть софтина, которая форкает детей и, соответственно, должна обрабатывать их завершение. У нее есть встроенный HTTP сервер с web интерфейсом.

Логично, что сигналы хочется обрабатывать исключительно в главном треде, поэтому перед созданием потока web сервер все сигналы блочатся, затем разблокируются как было и запускается цикл с sigwait и далее waitpid с WNOHANG.

Все работает, но! В веб интерфейсе понадобилось видеть результат выполнения сторонних комманд. И тут начинаются проблемы. Похоже, в зависимости от того, как лягут карты в шедулере, возможны две ситуации:

- До завершения ребенкаб в web треде успевает запуститься wait() из pclose() - тогда pclose возвращает 0, т.е. как бы все ok. sigwait в главном треде возвращается, и waitpid возвращает ECHILD, т.е. детей как бы нет.
- Ребенок завершается до pclose(), тогда главный поток ловит полноценного дохлого ребенка. pclose() в web треде возвращает -1, потому что ребенка уже нету.

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

Решение вижу такое: руками сделать fork, pipe, в ребенке daemon и exec/system. Таким образом сигнала мы уже точно не получим, потому что daemon, а данные спокойно прочитаем из пайпа и закроем его. Ну код завершения не сможем узнать - это, в принципе, не критично.

★★★★★

ИМХО взаимодействие лучше организовать через poll и unix sockets. Писать немного больше, но будет намного более универсально. Приложение-команда устанавливает «соединение» с родительским Web сервером, совершает с ним обмен данными по произвольной схеме, а по завершении работы закрывает соединение. Закрытие соединения всегда будет однозначно говорить о том что «конкретный» процесс завершил работу (либо корректно завершился,либо упал). Правда все равно надо не забыть про «зомби-процессы».

pathfinder ★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.