2016-04-12 2 views
0

Если я посылаю кучу сигналов SIGIO процессу, и этот процесс блокирует сигналы SIGIO и делает что-то еще. Когда я разблокирую сигнал, будет ли один сигнал SIGIO или несколько сигналов SIGIO в последовательности?Каково поведение блокировки сигнала?

+0

Я оставляю это как комментарий, а затем ответ, в исследовании этого некоторое время.. назад дал мне головную боль, и я не уверен, что все в порядке ... из того, что я понял, ответ «Да» ... он даст вам либо несколько сигналов, либо один сигнал, это как сигнал и зависит от реализации. Большинство сигналов будут слиты (только один сигнал будет получен), но некоторые могут сохраняться (некоторые сигналы ввода-вывода переносят метаданные, которые не должны сливаться, это может быть зависимым от ОС) ... удача с охотой . ** Я рекомендую вам указать, какие сигналы вы запрашиваете **. – Myst

+2

Будет ли одна или несколько доставки, ответ зависит от этого. возможный дубликат этого: http://stackoverflow.com/questions/6343871/about-the-delivery-of-standard-signals – fluter

ответ

0

Ответ - это зависит.

Сначала передаваемый сигнал обрабатывается методом обработчика. Для обработчика есть две части: верхняя и нижняя. Верх должен быть быстрым, он должен получить сигнал и установить некоторый флаг и вернуться. Нижняя часть проверяет этот флаг и затем отвечает. Теперь какая-то система Linux/UNIX сбрасывает обработчик на значение по умолчанию, когда происходит сигнал (так что вам нужно сбросить sigaction для этого сигнала в вашем обработчике).

Сигналы будут стоять в очереди, но только несколько (в зависимости от реализации). Если вы посылаете сигнал с помощью сигналов, вы можете потерять все те, которые возникают после заполнения очереди.

Посмотрите на сигнал и сигмацию на страницах руководства.

Решения AIX/Linux. Сначала установите обработчик.

sigset_t mask; 
sigemptyset(&mask); 

#ifdef AIX 
exitaction.sa_handler = C_signalExit; 
exitaction.sa_mask = mask; 
exitaction.sa_flags = SA_OLDSTYLE; 
#else // LINUX 
sigaddset(&mask, SIGHUP); 
sigaddset(&mask, SIGQUIT); 
sigaddset(&mask, SIGTERM); 
exitaction.sa_sigaction = C_signalActionExit; 
exitaction.sa_mask  = mask; 
exitaction.sa_flags  = SA_SIGINFO; 
#endif 

Теперь код обработчика (вверху) - Обратите внимание, здесь я должен был «придать обходной путь» для обработки сигналов на Linux (но по-прежнему держать код совместим с AIX) SystemOS класс, который обрабатывает сигналы и другие Операции, связанные с ОС.

#ifdef AIX 
void C_signalExit(int signal) { sys->signalExit(signal,0,NULL); } 
void SystemOS::signalExit(int signal, int code, struct sigcontext *sigcon) 
#else // LINUX 
void C_signalActionExit(int signal, siginfo_t* siginfo, void *data) 
{ sys->actionExit(signal,siginfo,data); } 

void SystemOS::actionExit(int signal, siginfo_t* siginfo, void* data) 
#endif 
{ 
    switch(signal) 
    { 
    case SIGINT : // interrupt from keyboard (^C ??) 
    case SIGKILL : // can't be caught or ignored // 080209 can't be blocked with sigblock() fields set si_pid,si_uid - see sigqueue(3) 
    case SIGTSTP : // ^Z 
    case SIGTTIN : // background read 
    case SIGTTOU : // background rite 
#ifdef AIX 
    case SIGDANGER: // disk space 
    case SIGPRE : // program exception 
    case SIGSAK : // secure attention 
#endif 
    default : 
     exec.kill(signal,SIGNAL_ERROR); // exec is the 'main program' 
    } 
} 

Ex.kill будет нижней половиной - он принимает сигнал и значение и убьет приложение. Вы бы иметь некоторую другую функцию там (это не стандартный метод - но часть моей структуры приложения

Я надеюсь, что это помогает

+0

PS: инструкция switch существует для будущего расширения - в случае необходимости конкретного другого действия , В этом примере все сигналы обрабатываются по умолчанию (то есть все случаи «впадают» в последний случай (по умолчанию: case)) – Thaddeus

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