SIGUSR1
и другие сигналы POSIX не поставлены в очередь. Если в процессе уже есть один ожидающий, любые другие сигналы будут отброшены.
Вы можете избежать этого, используя «сигналы в реальном времени». Вы используете их так же, как вы используете стандартные сигналы POSIX; первый - SIGRTMIN+0
, а последний - SIGRTMAX-0
. Если вы используете sigqueue()
, вы можете даже приложить один int
(или указатель на пустоту) в качестве полезной нагрузки.
Сигналы в реальном времени POSIX находятся в очереди (до предела), поэтому вы с меньшей вероятностью потеряете их.
Однако я не использовал бы сигналы для отслеживания дочерних процессов. Я использовал бы трубы, у которых были бы концы записи, а родительский с концами чтения и все дескрипторы, помеченные для close-on-exec, используя fcntl(descriptor, O_SETFD, O_CLOEXEC)
для каждого.
Дети обновляют родительский статус при помощи однобайтовых сообщений. Если ребенок выйдет или выполнит другую программу, родитель увидит это как условие окончания файла (read()
, возвращающий ноль). Если родительский элемент завершен, конец записи станет неприемлемым для конца записи для ребенка, и любая попытка записи в трубу завершится ошибкой с ошибкой EPIPE
. (Это будет также поднять SIGPIPE
сигнал, так что вы можете захотеть использовать sigaction()
игнорировать SIGPIPE
сигнал.)
родитель может контролировать процесс ребенка статусы параллельно с использованием select()
или poll()
. Всякий раз, когда дочерний процесс отправляет данные или выдает или выполняет другую программу (которая закрывает конец записи в трубе), родительский дескриптор (считываемый конец канала) станет читаемым. Лично я также отмечаю, что дескрипторы родительских дескрипторов не блокируются с использованием fcntl(rfd, F_SETFL, O_NONBLOCK)
, так что если есть глюк, вместо того, чтобы блокировать неверное чтение, чтение на родительском компьютере просто завершится ошибкой с EWOULDBLOCK
в errno.
Если вы хотите использовать двунаправленный поток данных, проще всего использовать дополнительный канал для каждого ребенка, родительскую запись и чтение ребенка из него.
Также можно использовать неназванные сокеты datagram домена Unix (созданные через socketpair(AF_UNIX, SOCK_DGRAM, 0, fds)
. (См. Также man 2 socket и man 7 unix для получения подробной информации о параметрах.) Также используйте fcntl(fds[0], F_SETFL, O_CLOEXEC)
и fcntl(fds[1], F_SETFL, O_CLOEXEC)
, чтобы сделать дескрипторы close-on-exec, как и в случае с корпусом.
Проблема с парами сокет домена Unix (любого типа - SOCK_STREAM
, SOCK_DGRAM
, SOCK_SEQPACKET
), является то, что они могут содержать вспомогательные данные . Эти вспомогательные данные могут содержать дополнительные файловые дескрипторы, которые являются ограниченным товаром. Если есть возможность ненадежного или неприятного дочернего процесса, он может убить своего родителя, отправив ему несколько тысяч дескрипторов файлов. Для обеспечения безопасности родительский процесс должен следить за тем, что он получает от дочернего процесса, и если он содержит вспомогательные данные, немедленно закройте этот дескриптор (поскольку дочерний процесс явно враждебен!), И если были предоставлены какие-либо файловые дескрипторы, закройте их тоже. Вы можете избежать этого, только если вы доверяете своему ребенку процессы, насколько вы доверяете своему первоначальному процессу, чтобы не делать ничего гнусного.
Обеспечение безопасности сокетов домена unix не сложно, но проверка каждой полученной дейтаграммы или получение для вспомогательных данных - это пара десятков дополнительных строк кода. Трубы проще.
Описывая текст в тексте очень неоднозначно, попробуйте создать [Минимальный, полный и проверенный пример] (http://stackoverflow.com/help/mcve) и покажите нам, а если есть выход, пожалуйста, предоставьте фактический и ожидаемый результат. –
Есть так много вещей, которые могли бы пойти не так, мы не можем помочь вам, не имея хотя бы MCVE, как сказал Йоахим. Откуда вы знаете, какой ребенок отправил каждый сигнал? Откуда вы знаете, что родитель успешно отправил каждому из детей сигнал? Мы не можем начинать угадывать ответы на такие вопросы, не видя кода. –
его в сигналах природа ненадежна :) – shami