Каково поведение блокировки сигнала?
Если я посылаю кучу сигналов SIGIO процессу и тому блоку сигналов SIGIO и выполняю что-то еще. Когда я разблокирую сигнал, будет ли в последовательности только один сигнал SIGIO или несколько сигналов SIGIO?
1 ответ
Ответ... это зависит.
Сначала отправляемый сигнал обрабатывается методом-обработчиком. Обработчик состоит из двух частей: верхней и нижней. Верх должен быть быстрым, он должен получить сигнал, установить флаг и вернуться. Нижняя часть проверит этот флаг, а затем ответит. Теперь некоторые системы 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'
}
}
Exec.kill будет нижней половиной - он принимает сигнал и значение и убивает приложение. У вас там будет какая-то другая функция (это не стандартный метод - но часть моей инфраструктуры приложений).
Надеюсь, это поможет.