如果我向进程发送一堆SIGIO信号,那个进程阻止SIGIO发出信号并做其他事情。当我取消阻塞信号时,是否只有一个SIGIO信号或多个SIGIO信号依次发生?
答案 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框架的一部分。
我希望这会有所帮助。