Каково поведение блокировки сигнала?

Если я посылаю кучу сигналов 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 будет нижней половиной - он принимает сигнал и значение и убивает приложение. У вас там будет какая-то другая функция (это не стандартный метод - но часть моей инфраструктуры приложений).

Надеюсь, это поможет.

Другие вопросы по тегам