【问题标题】:What is the behavior of blocking a signal?阻塞信号的行为是什么?
【发布时间】:2016-08-02 09:54:59
【问题描述】:

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

【问题讨论】:

  • 我将此作为评论而不是答案,因为不久前研究这个让我头疼,我不确定我是否一切正常......据我了解,答案是“是”......它会给你几个信号或一个信号,这既取决于信号又取决于实现。大多数信号将合并(只会收到一个信号),但有些可能会持续存在(一些 IO 信号携带不应合并的元数据,这可能取决于操作系统)......祝你好运。 我建议您指定您要询问的信号
  • 是单发还是多发,答案看情况而定。也可能与此重复:stackoverflow.com/questions/6343871/…

标签: c signals sigprocmask


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

我希望这会有所帮助。

【讨论】:

  • PS : switch 语句用于将来的扩展 - 以防需要特定的其他操作过程。在这个例子中,所有的信号都被默认处理(即所有的情况都“落入”最后一种情况(默认:case))
猜你喜欢
  • 2016-05-24
  • 1970-01-01
  • 2014-12-27
  • 1970-01-01
  • 1970-01-01
  • 2020-02-29
  • 2022-10-19
  • 1970-01-01
  • 2011-04-24
相关资源
最近更新 更多