0

如果我向一个进程发送一堆 SIGIO 信号并且该进程阻止 SIGIO 信号并执行其他操作。当我解除阻塞信号时,会只有一个 SIGIO 信号还是依次有多个 SIGIO 信号?

4

1 回答 1

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 是处理信号和其他 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 将是下半部分 - 它接收信号和值并将终止应用程序。你会有一些其他的功能(它不是标准方法 - 但我的应用程序框架的一部分。

我希望这有帮助。

于 2016-04-12T02:17:18.053 回答