[sisyphus] Q: Очень непростой вопрос на тему select() и сигналов
Mikhail Efremov
sem на altlinux.ru
Пт Апр 10 03:49:37 MSD 2009
On Friday 10 April 2009 02:48:34 Michael Pozhidaev wrote:
> Схематически код выглядит так:
>
> int there_was_sigchld = 0;
Насколько я помню, единственный тип, который POSIX разрешает использовать для
этого - sig_atomic_t. Да, это скорее всего typedef int, но если уж говорить
об аккуратности...
>
> void main_loop()
> {
> while(1)
> {
> block_sigchld();
> check_sigchld();
> pselect(required_fds, and_signal_mask_with_enabled_sigchld);
> check_data_from_fds_if_there_was_any();
> }
> }
Да, что-то вроде
if (pselect(required_fds, and_signal_mask_with_enabled_sigchld) <0)
if(errno == EINTR)
check_sigchld();
> Если должно быть так, то что произойдёт, если sigchld пришёл в тот
> краткий момент, когда он был заблокирован? pselect() увидит, что пока
> сигнал был заблокирован, он приходил, и нужно сразу прекратить ожидание,
> вызвать его обработчик и дать программе его обработать? Если нет, то
> тогда мы вообще теряем получение SIGCHLD. Ещё есть интересная функция
> sigpending(), но уместна ли она здесь, вот это непонятно.
Блокировка сигнала != игнорирование сигнала. Блокированный сигнал не
потеряется, просто не будет вызван обработчик пока его не разблокируют, что и
делает pselect. А sigpending() думаю тут не нужен.
По поводу реализации pselect в Linux не знаю, тут видимо надо сам его код
смотреть, но man подсказывает альтернативное решение:
On systems that lack pselect(), reliable (and more portable) signal trapping
can be achieved using the self-pipe trick (where a signal handler writes a
byte to a pipe whose other end is monitored by select() in the main
program.)
--
WBR, Mikhail Efremov
Подробная информация о списке рассылки Sisyphus