简体   繁体   English

阻止信号的行为是什么?

[英]What is the behavior of blocking a signal?

If I send a bunch of SIGIO signals to a process and that process block SIGIO signals and doing something else. 如果我向进程发送了一堆SIGIO信号,并且该进程阻止了SIGIO信号并执行其他操作。 When I unblock the signal, will there be only one SIGIO signal or multiple SIGIO signals in sequence? 当我解除阻塞信号时,会依次出现一个SIGIO信号还是多个SIGIO信号?

The answer is ... it depends. 答案是……这取决于。

First the signal that is being sent is 'handled' by a handler method. 首先,通过处理程序方法“处理”正在发送的信号。 There are two parts to a handler: top and bottom. 处理程序分为两部分:顶部和底部。 The top should be quick, it should get the signal and set some flag and return. 顶部应该很快,它应该获得信号并设置一些标志并返回。 The bottom part will check that flag and then respond. 底部将检查该标志,然后响应。 Now some Linux/UNIX system reset the handler to the default when a signal happens (so you have to reset the sigaction for that signal in your handler). 现在,某些Linux / UNIX系统在发生信号时将处理程序重置为默认值(因此您必须在处理程序中重置该信号的信号)。

Signals will queue up, but only a few (depending upon the implementation). 信号将排队,但只有少数(取决于实现方式)。 If you are sending alog of signals you could loose all those that occur after the queue fills. 如果您要发送信号日志,则可以松开队列填充后发生的所有信号。

Look at signal and sigaction in man pages. 在手册页中查看信号和提示。

Here is an AIX/Linux solution. 这是一个AIX / Linux解决方案。 First setting the handler. 首先设置处理程序。

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

Now the handler code (top) - Note here I had to 'inject a workaround' to handle signals on Linux (but still keep the code compatible with AIX) SystemOS is the class that handles signals and other OS related activities. 现在是处理程序代码(顶部)-注意这里我必须“注入解决方法”以在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' 
   }
} 

The exec.kill would be the bottom half - it takes the signal and value and will kill the application. exec.kill将是下半部分-它接收信号和值并杀死应用程序。 You'd have some other function there (its not a standard method - but part of my app framework. 您在那里还有其他功能(它不是标准方法-而是我的应用程序框架的一部分)。

I hope this helps. 我希望这有帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM