2011-12-28 2 views
2

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

при запуске выше команду три раза последовательно, 3-й сигнал будет проигнорирован как показано в следующем выводе:

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

Сон в обработчике сигнала сомнительный. Это должно быть там? – wallyk

+0

@wallyk В соответствии с страницей руководства, POSIX.1-2004 требует, чтобы 'sleep' был безопасным в обработчике сигналов. –

+0

нормальные сигналы не поставлены в очередь, вы будете скучать, независимо от того, что вы делаете. – nos

ответ

2

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

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

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

1

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

+0

, когда я ввожу 'ulimit -a' в свой linux, я вижу, что' pending signals' имеет значение по умолчанию 16383. Я тестировал его также с 'getrlimit' и именем ресурса' RLIMIT_SIGPENDING' (это снова 16383). Итак, как linux обрабатывает это количество ожидающих сигналов только одним битом? – saeedn

+0

@saeedn Это общее количество сигналов, которые могут быть отложены на каждого пользователя (фактически на «настоящий идентификатор пользователя») за каждый процесс. Для одного сигнала за каждый процесс может быть только один сигнал каждого типа. –

Смежные вопросы