LINUX.ORG.RU

Может ли ядро Linux терять сигналы

 ,


0

1

Здравствуйте, уважаемые.

Возник тут вопрос, ответ на который, скорее всего могут подсказать знатоки ядра.

Однопоточное приложение, у которого разблокированы все сигналы и выставлены обработчики на SIGINT, SIGTERM, SIGQUIT. Вобщем считаем, что все необходимые условия для того, чтобы программа приняла и обработала сигнал есть. Другое приложение отправляет первому, например, SIGINT. Может ли случиться такое, что приложению НЕ дойдет отправленый сигнал? То есть отправленый сигнал система не доведет до приложения. По времени доставки ограничений нет. Дополнительно система нагружена по самое-самое другими приложениями: cpu - 90..100%, есть дефицит ресурсов (RAM, io), своп отсутствует и т.п.

Размер очереди сигналов для приложение был равен 1 (по каждому из сигналов). Если приложению будет отправлено два сигнала SIGINT «одновременно», то дойдёт только один.

Под «одновременно» я подразумеваю отправку сигналов до того, как был вызван обработчик сигналов приложения. То есть приложению был отправлен сигнал SIGINT, и до того, как планировщик выбрал приложение к выполнению, был отправлен второй сигнал SIGINT.

Если же отправляется один сигнал SIGINT, то он дойдёт всегда, (если только его не «опередит» SIGKILL), так как, ЕМНИП, при обработке системного вызова по отправке сигнала ядро сразу же, в рамках выполнения этого сискола, записывает этот сигнал в очередь адресата сигнала. И как только приложение получит квант процессорного времени, будет обработана его очередь сигналов.

mky ★★★★★
()
Последнее исправление: mky (всего исправлений: 1)
Ответ на: комментарий от mky

Хм. Т.е. использовать сигналы для управления каким-то демоном (вместо того, чтобы городить сокеты или ещё чего-то с кучей кода) идея глупая и так делать нельзя?
Спасибо за информацию.

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

Смотря что подразумевать под управлением. Если перечитать конфиг, ротировать логи, завершить работу, то это одно. А если демон должен менять своё внутреннее состояние и сигналы ему отправляются другим демоном, то нужен контроль, что дошло именно нужное кол-во сигналов. Как-то так.

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

Если вы слышали выражение «потерянный сигнал», то речь шла о неправильной обработке последовательности сигналов, или о старой их семантике. У вас все просто.

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

А как вообще возник вопрос

Да вот один деятель тут где-то вычитал (или сам придумал) фразу, что сигналы в линуксе «ненадежный механизм»... Он же и выдал, что сигнал может не дойти и потеряться. Поскольку я не копал глубоко ядро, вопрос и возник. А вообще задача как раз корректно остановить приложение по сигналу с освобождением ресурсов. У меня программа спит в select()'е и по EINTR оглядывается на флаги вокруг. Флаг завершения работы выставляется в обработчике сигнала как раз. Судя по ответу mky все законно.

или о старой их семантике

А можно по-подробнее? Приклад будет работать в том числе на ARM-Linux с ядром 2.6.18.

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

Ваш «деятель» слышал звон и не более того. В изначальном unix была невозможна абсолютно надежная обработка сигналов: изредка, в некоторых случаях, посланный сигнал мог не обработаться (например, между сбросом обработчика и его переустановкой). Очень давно семанику сигналов поменяли на новую, «надежную».

А перехватить сигнал и завершиться - это простейший случай, который всегда работал надежно.

Все расписано, емнип, у Стивенса. В ядро лезть не имеет смысла )

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

Ага, спасибо за наводку. Очень похоже, на то, что вы описали выше. Думаю вопрос можно закрыть.

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

Все расписано, емнип, у Стивенса. В ядро лезть не имеет смысла )

В принципе вы правы, сейчас освежу в памяти заветы стивенса. Тем не менее в ядро посмотрел. Хуже от этого не будет. Ну а «деятель» у нас тут с клиническими симптомами. Впрочем, это уже совсем другая история ;-)

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

У меня программа спит в select()'е и по EINTR оглядывается на флаги вокруг

сигнал может прийти и не во время работы селекта, поэтому флаг, устанавливаемый обработчиком сигнала, надо проверять периодически независимо от кода возврата сискола

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

signalfd + select

при таком раскладе посмотрите на signalfd - очень уж под Ваш кейс подходит, и, вроде как, глубина вложенности более 1 сигнала, но тут лучше перепроверить ;)

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

У меня программа спит в select()'е и по EINTR оглядывается на флаги вокруг.

Типичная ошибка в этом случае, это код типа:

if ( ! flag ) select(nfds, readfds, writefds,exceptfds, NULL);

То есть, select() без таймаута. Сигнал может придти после проверки flag (выставляемого в обработчике) и перед вызовом select.

Поэтому, либо pselect(), либо таймаут в select() и проверка флага независимо от результата select(), либо ещё один файловый дескриптор в select(), который может быть, или signalfd(), или pipe'ом, в который пишет обработчик сигнала.

Старая семантика это signal(), новая это sigaction(), в ″man 2 signal″ есть раздел про его особенности, но потеря сигнала из-за использования signal() вместо sigaction() — это особенности стандарта, а не недостатки ядра. Но даже с signal() одиночный сигнал на завершение работы будет получен приложением.

mky ★★★★★
()
Последнее исправление: mky (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.