LINUX.ORG.RU

Сигнал во время ожидания ввода-вывода


0

0

Такая проблема. Программа получает данные через COM-порт, и основное время проводит в состоянии ожидания этих данных (в системном вызове read). Нужно чтобы она корректно обрабатывала сигнал TERM (т. е. правильно завершала свою работу). Но простая установка сигнала не помогает - при получении SIGTERM программа просто завершает работу с сообщением "Terminated.", мой обработчик сигнала вообще не вызывается. Подозреваю что дело тут как раз в том что сигнал приходит во время ожидания в системном вызове - видимо libc ставит на это время какой-то свой обработчик. Как с этим можно бороться - чтобы всё-таки получить этот сигнал?

★★

>Но простая установка сигнала не помогает - при получении SIGTERM программа просто завершает работу с сообщением "Terminated.", мой обработчик сигнала вообще не вызывается.

похоже на некорректную установку обработчика. код в студию

cvv ★★★★★
()

Во-1 покажи код.
Во-2 я искренне надеюсь, что ты используешь не signal() а sigaction()
для установки обработчика.

Onanim
()

>и основное время проводит в состоянии ожидания этих данных
>(в системном вызове read)

Хм? А select() использовать не пробовали??

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

>Хм? А select() использовать не пробовали??

на обработку сигналов select() никаким боком не влияет

cvv ★★★★★
()
Ответ на: комментарий от Onanim

Да, использую sigaction. Код установки обработчика вот:

	struct sigaction sa_term;
	sa_term.sa_handler=&term_handler;
	sa_term.sa_sigaction=0;
	sa_term.sa_flags=0;
	sigaction(SIGINT, &sa_term, 0);
	sigaction(SIGTERM, &sa_term, 0);

То что sa_term используется 2 раза для установки обработчкиов разных сигналов никак не влияет (проверял).

slav ★★
() автор топика
Ответ на: комментарий от braindef

> Хм? А select() использовать не пробовали??

А чем мне селект здесь поможет? У меня же только один источник данных, когда данных нет ничего считать не нужно... Обычный блокирующий read как раз подходит.

slav ★★
() автор топика
Ответ на: комментарий от slav

Всё, разобрался. Проблема была в том, что не надо было устанавливать в 0 sa_sigaction. Он с sa_handler, оказывается, в юнион объединён. А ввод-вывод тут вообще не при чём...

slav ★★
() автор топика
Ответ на: комментарий от Onanim

> Во-2 я искренне надеюсь, что ты используешь не signal() а sigaction() для установки обработчика.

Ну для SIGTERM оно как раз вполне иррелевантно, особенно если обработчик выглядит как

void handle_term(int signo) {should_exit++;}

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

> > Во-2 я искренне надеюсь, что ты используешь не signal() а sigaction() для установки обработчика

> Ну для SIGTERM оно как раз вполне иррелевантно,

Уверен? Подумай, что произойдет если ты установил handler при помощи
signal() c SysV семантикой и твой процесс получил два SIGTERM подряд.

> особенно если обработчик выглядит как
> void handle_term(int signo) {should_exit++;}

Да, наверное для такого обработчика опасность минимальна.

Но почему бы все равно не использовать sigaction() ?

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