Как получить более двух последовательных сигналов? - PullRequest
2 голосов
/ 28 декабря 2011

Если я отправлю несколько последующих 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 ]

2 голосов
/ 28 декабря 2011

Как правило, вы не можете сделать это со стандартными сигналами.Ядро Unix обычно ставит в очередь только один ожидающий сигнал.Если Sig2 и Sig3 отправляются, когда процесс находится в спящем режиме в обработчике Sig1, они объединяются.

Вы можете использовать sigaction (2) для настройки обработчика сигнала и предоставления ему флага SA_NODEFER.Это позволит доставлять новый сигнал, пока он находится в обработчике сигнала.Убедитесь, что ваш обработчик является повторно входящим, он подвержен ошибкам.

Также есть расширение POSIX.1b (POSIX.1-2001), называемое «сигналы в реальном времени».Такие сигналы могут быть поставлены в очередь несколько раз, но SIGHUP не является одним из них.signal (7) в Linux гласит, что сигналы реального времени пронумерованы от 33 (SIGRTMIN) до 64 (SIGRTMAX).

1 голос
/ 28 декабря 2011

В Linux ожидающие сигналы представлены только одним битом.Это означает, что если несколько сигналов генерируются, когда обработчик уже запущен, он будет вызван только еще раз.

...