LINUX.ORG.RU

fork/exec и взаимодействие процессов


0

0

Всем привет. Возник тут такой вопрос к товарищам с опытом системного программирования.
C++. Есть демон, который висит на порту и слушает входящие сокеты - читает/обрабатывает/отвечает. Реализация очереди - на libev. Время обработки запроса - в пределах нескольких секунд, однако некоторые запросы требуют выполнения громоздких (по времени исполнения) команд в шелл - в таких ситуациях нужно:
а) перевести демон в определенное состояние;
б) запустить отдельным тредом выполнение команд
в) отдать клиенту ответ и закрыть сокет;
г) во время выполнения команд продолжать обработку запросов;
д) после выполнения команд перевести демон в исходное состояние;
е) продолжать обработку запросов.
Для запуска команд запускаю тред, в котором вфоркаюсь (где child выполняет execl, а parent пишет ответ в сокет) и у child убиваю все открытые дескрипторы (для того, чтобы parent смог ответить клиенту и закрыть сокет не ожидая завершения execl).
Корявость возникла с "д)" - переводом демона в исходное состояние после отработки команд: для того, чтобы child смог дать отмашку parent-у, пришлось в последний добавить обработчик SIGUSR1, а в список команд, выполняемых execl в child, добавить "kill -10 parentpid" (parentpid получаю перед форканьем). Все отлично работает, но решение мне не нравится - если таких состояний будет не 1-2, а сотня, то сигналов уже не хватит + не покидает ощущение, что ломлюсь в открытые ворота. Может быть можно эту проблему решить как-то по-другому, проще? Oрганизовать межпроцессную связь через FIFO или pipe нельзя, т.к. все ранее открытые дескрипторы у child нужно закрывать после форка. А нельзя ли как-то организовать выполнение системных команд в треде этого же процесса вообще без форка/вфорка?

Я в свое время делал так:

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

Ну как то так. Или я что то не так понял?

Torvus
()
Ответ на: комментарий от ratatosk

> В линуксе на сокет можно поставить SOCK_CLOEXEC при вызове socket. Но это linux specific.

fcntl F_SETFD FD_CLOEXEC

const86 ★★★★★
()

Большое спасибо всем ответившим, FD_CLOEXEC - самое то! А на вырост shm будет )

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