如果我向一个进程发送一堆 SIGIO 信号并且该进程阻止 SIGIO 信号并执行其他操作。当我解除阻塞信号时,会只有一个 SIGIO 信号还是依次有多个 SIGIO 信号?
问问题
350 次
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 回答