Можно ли игнорировать сигнал (потерять)?

У меня есть приложение, которое общается с рабочими через сигналы (в частности SIGUSR1 / SIGUSR2 / SIGSTOP).

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

Что произойдет, если сигналы будут отправлены быстрее, чем это возможно для приложения для их обработки (например, из-за высокой загрузки хоста в данный момент)?

  • отправить сигнал на команду
  • Декодировать флаги для команды Kill
  • Как определить номера сигналов, используя strace в приложении?
  • Могу ли я приостановить процесс («стресс»), чтобы имитировать давление памяти за вычетом стоимости процессора?
  • Отключите отображение информации о «завершенном xxx» в bash
  • Эквивалент «truss -T» и «truss -U» в Linux?
  • SIGKILLing после льготного периода
  • Есть ли утилита Linux для остановки всех пользовательских процессов, включая виртуальную машину?
  • 4 Solutions collect form web for “Можно ли игнорировать сигнал (потерять)?”

    Помимо проблемы «слишком много сигналов», сигналы могут быть явно проигнорированы. Из man 2 signal :

     If the signal signum is delivered to the process, then one of the following happens: * If the disposition is set to SIG_IGN, then the signal is ignored. 

    Сигналы также могут быть заблокированы. Из man 7 signal ;

     A signal may be blocked, which means that it will not be delivered until it is later unblocked. Between the time when it is generated and when it is delivered a signal is said to be pending. 

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

    Что происходит, когда несколько сигналов доставляются до того, как процесс завершит обработку предыдущих? Это зависит от ОС. Связанная выше ссылка signal(2) manpage обсуждает это:

    • Система V сбросит настройку сигнала по умолчанию. Хуже того, быстрая доставка нескольких сигналов приведет к рекурсивным вызовам (?).
    • BSD автоматически блокирует сигнал до тех пор, пока обработчик не будет выполнен.
    • В Linux это зависит от флагов компиляции, установленных для GNU libc , но я бы ожидал поведения BSD.

    Вы не можете доверять, что каждый отправленный сигнал будет доставлен. Например, ядро linux «сглаживает» SIGCHLD, если процесс занимает много времени при обработке SIGCHLD из выходящего дочернего процесса.

    Чтобы ответить на другую часть вашего вопроса, сигналы попадают «в очередь» внутри ядра, если количество разных сигналов поступает слишком близко к интервалу.

    Вы должны использовать sigaction() чтобы настроить обработчик сигнала с sa_sigaction члена siginfo_t , тщательно siginfo_t параметр siginfo_t аргумента siginfo_t . Я думаю, что это означает, что, по крайней мере, маскировать все «асинхронные» сигналы. Согласно странице man для sigaction() Linux, вы также будете маскировать обрабатываемый сигнал. Я думаю, вы должны установить член sa_flags в SA_SIGINFO, но я не могу вспомнить, почему у меня есть это суеверие. Я считаю, что это приведет к тому, что ваш процесс будет обработчиком сигнала, который остается без условий гонки, и тот, который не прерывается большинством других сигналов.

    Напишите свою функцию обработчика сигнала очень, очень осторожно. В основном просто установите глобальную переменную, чтобы указать, что сигнал пойман, и остальная часть процесса связана с желаемым действием для этого сигнала. Сигналы будут маскироваться в течение наименьшего количества времени таким образом.

    Кроме того, вы захотите проверить код обработки сигнала очень тщательно. Поместите его в небольшой тестовый процесс и отправьте как можно больше сигналов SIGUSR1 и SIGUSR2, возможно, от 2 или 3 специальных программ отправки сигналов. Смешивайте и в некоторых других сигналах, после того как вы доверяете, что ваш код может быстро и правильно обрабатывать SIGUSR1 и SIGUSR2. Подготовьтесь к сложной отладке.

    Если вы используете linux и только linux, вы можете подумать об использовании signalfd() чтобы создать файловый дескриптор, который вы можете select() или опросить, чтобы получать эти сигналы. Использование функции signalfd() может облегчить отладку.

    Гарантируется, что сигнал будет доставлен в том смысле, что если процесс успешно вызывает kill , то цель получит сигнал. Это асинхронно: отправитель не имеет возможности узнать, когда сигнал получен или обработан. Однако это не гарантирует, что сигнал будет доставлен. Цель может умереть, прежде чем она сможет обработать сигнал. Если цель игнорирует сигнал в момент его доставки, сигнал не будет иметь никакого эффекта. Если цель получает несколько экземпляров одного и того же номера сигнала, прежде чем он сможет их обработать, сигналы могут (и обычно) сливаться: если вы отправляете один и тот же сигнал дважды в процесс, вы не можете знать, получит ли процесс сигнал один или два раза. Сигналы в основном предназначены для того, чтобы убить процесс или как способ обратить внимание на процесс, они не предназначены для коммуникации как таковой.

    Если вам нужна надежная доставка, вам нужен другой механизм связи. Между процессами существуют два основных механизма связи: труба допускает однонаправленную связь; сокет позволяет двунаправленную связь и несколько соединений с одним и тем же сервером. Если вам нужна цель для обработки как можно большего количества уведомлений, отправляйте ее по каналу.

    Ядро может свободно объединяться с стандартными сигналами, если в него блокируется более одного. Сигналы в реальном времени, с другой стороны, не так же ограничены.

    Из справочной страницы с сигналом (7) :

    Сигналы в реальном времени отличаются следующим:

    1. Несколько экземпляров сигналов в реальном времени могут быть поставлены в очередь. Напротив, если несколько экземпляров стандартного сигнала доставляются, пока этот сигнал заблокирован, тогда очередь помещается только в один экземпляр.

    Попробуйте использовать сигнал с номером в диапазоне SIGRTMIN до SIGRTMAX.

    Interesting Posts

    Проверьте, работает ли процесс в привилегированном режиме

    Можно ли изменить порядок позиций в постоянном буфере обмена Parcellite?

    Уменьшение отпечатка на stdout, если весь файл может отображаться на одном экране

    Linux, где находятся системные вызовы sys_umount и sys_mount?

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

    Пользовательское заполнение bash с каталогами и фиксированным набором

    Как получить журнал из u-boot без ком-порта

    Как выровнять мой новый subbolf по умолчанию btrfs с реальным корнем моей файловой системы?

    Ошибка миграции Plesk 10

    Eclipse не является исполняемым

    'who –message' -> какое сообщение?

    Как найти конкретную строку и распечатать всю строку?

    telnet для хоста / порта работает, пока на этом хосте не прослушивается сервис на этом порту

    как использовать rsync (используя ssh без пароля), с sudo только на локальной стороне?

    Debian – сеть не работает при загрузке

    Linux и Unix - лучшая ОС в мире.