[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