Как получить более двух последовательных сигналов?
Если я отправлю несколько последующих Hangup
сигналы для следующей программы, только две из них будут обработаны, а остальные будут игнорироваться:
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
int id;
void handler(int s)
{
id++;
int i;
for(i=0; i<3; i++)
{
printf("Sig %d\n", id);
sleep(2);
}
}
int main()
{
int i;
signal(SIGHUP, handler);
for( i=0; ; i++ )
{
printf("%d\n", i);
sleep(1);
}
return 0;
}
Я использую следующую команду для отправки сигнала процессу:
kill -l {#process}
Если я выполню указанную выше команду три раза подряд, третий сигнал будет проигнорирован, как показано в следующем выводе:
0
1
2
3
4
5
6
7
Sig 1
Sig 1
Sig 1
Sig 2
Sig 2
Sig 2
8
9
10
11
12
Есть ли способ поймать третий сигнал тоже?
2 ответа
Как правило, вы не можете сделать это со стандартными сигналами. Ядро Unix обычно ставит в очередь только один ожидающий сигнал. Если Sig2 и Sig3 отправляются во время ожидания процесса в обработчике Sig1, они объединяются.
Вы можете использовать sigaction(2) для настройки вашего обработчика сигнала и установки для него флага SA_NODEFER. Это позволит доставлять новый сигнал, пока он находится в обработчике сигнала. Убедитесь, что ваш обработчик является реентерабельным, это подвержено ошибкам решение.
Также есть расширение POSIX.1b (POSIX.1-2001), называемое "сигналы в реальном времени". Такие сигналы могут быть поставлены в очередь несколько раз, но SIGHUP не является одним из них. signal(7) в Linux утверждает, что сигналы в реальном времени пронумерованы от 33 (SIGRTMIN) до 64 (SIGRTMAX).
В Linux ожидающие сигналы представлены только одним битом. Это означает, что если несколько сигналов генерируются, когда обработчик уже запущен, он будет вызван только еще раз.