阻塞信号的行为是什么?

时间:2016-04-12 01:46:21

标签: c signals sigprocmask

如果我向进程发送一堆SIGIO信号,那个进程阻止SIGIO发出信号并做其他事情。当我取消阻塞信号时,是否只有一个SIGIO信号或多个SIGIO信号依次发生?

1 个答案:

答案 0 :(得分:0)

答案是......这取决于。

首先,正在发送的信号由处理程序方法“处理”。处理程序有两个部分:顶部和底部。顶部应该很快,它应该得到信号并设置一些标志并返回。底部将检查该标志然后响应。现在,一些Linux / UNIX系统在信号发生时将处理程序重置为默认值(因此您必须在处理程序中重置该信号的sigaction)。

信号将排队,但只有少数(取决于实施)。如果您发送信号,则可能会丢失队列填充后发生的所有信号。

查看手册页中的信号和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是处理信号和其他OS相关活动的类。

#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将是下半部分 - 它接受信号和值并将杀死应用程序。你还有其他一些功能(它不是标准方法 - 但是我的app框架的一部分。

我希望这会有所帮助。