了解信号,我想知道过程信号掩码,阻塞信号集,信号处理程序和阻塞信号之间的细微差别。
问题涉及(在Debian上):
每个进程都有自己的信号掩码(包含被阻塞信号的长整数)。并且可以通过使用* set变量的NULL参数调用sigprocmask(2)来获得信号集,这将导致旧的进程掩码被放入* oldset,不变:
#include <string.h>
#include <signal.h>
void show_signals(const sigset_t exmask)
{
int exsignals[43];
exsignals[0] = SIGABRT;
exsignals[1] = SIGALRM;
exsignals[2] = SIGBUS;
exsignals[3] = SIGCHLD;
exsignals[4] = SIGCONT;
#ifdef SIGEMT
exsignals[5] = SIGEMT;
#else
exsignals[5] = -1;
#endif
exsignals[6] = SIGFPE;
#ifdef SIGFREEZE
exsignals[7] = SIGFREEZE;
#else
exsignals[7] = -1;
#endif
exsignals[8] = SIGHUP;
exsignals[9] = SIGILL;
#ifdef SIGINFO
exsignals[10] = SIGINFO;
#else
exsignals[10] = -1;
#endif
exsignals[11] = SIGINT;
exsignals[12] = SIGIO;
exsignals[13] = SIGIOT;
#ifdef SIGJVM1
exsignals[14] = SIGJVM1;
#else
exsignals[14] = -1;
#endif
#ifdef SIGJVM2
exsignals[15] = SIGJVM2;
#else
exsignals[15] = -1;
#endif
exsignals[16] = SIGKILL;
#ifdef SIGLOST
exsignals[17] = SIGLOST;
#else
exsignals[17] = -1;
#endif
#ifdef SIGLWP
exsignals[18] = SIGLWP;
#else
exsignals[18] = -1;
#endif
exsignals[19] = SIGPIPE;
exsignals[20] = SIGPOLL;
exsignals[21] = SIGPROF;
exsignals[22] = SIGPWR;
exsignals[23] = SIGQUIT;
exsignals[24] = SIGSEGV;
exsignals[25] = SIGSTKFLT;
exsignals[26] = SIGSTOP;
exsignals[27] = SIGSYS;
exsignals[28] = SIGTERM;
#ifdef SIGTHAW
exsignals[29] = SIGTHAW;
#else
exsignals[29] = -1;
#endif
#ifdef SIGTHR
exsignals[30] = SIGTHR;
#else
exsignals[30] = -1;
#endif
exsignals[31] = SIGTRAP;
exsignals[32] = SIGTSTP;
exsignals[33] = SIGTTIN;
exsignals[34] = SIGTTOU;
exsignals[35] = SIGURG;
exsignals[36] = SIGUSR1;
exsignals[37] = SIGUSR2;
exsignals[38] = SIGVTALRM;
#ifdef SIGWAITING
exsignals[39] = SIGWAITING;
#else
exsignals[39] = -1;
#endif
exsignals[40] = SIGWINCH;
exsignals[41] = SIGXCPU;
exsignals[42] = SIGXFSZ;
#ifdef SIGXRES
exsignals[43] = SIGXRES;
#else
exsignals[43] = -1;
#endif
int exsignals_n = 0;
for (;exsignals_n < 43; exsignals_n++) {
if (exsignals[exsignals_n] == -1) continue;
static char *exsignal_name;
exsignal_name = strsignal(exsignals[exsignals_n]);
switch(sigismember(&exmask, exsignals[exsignals_n]))
{
case 0: break;
case 1: printf("YES %s\n", exsignal_name); break;
case -1: printf("could not obtain signal\n"); break;
default: printf("UNEXPECTED for %s return\n", exsignal_name); break;
}
}
}
const sigset_t getmask(void)
{
static sigset_t retmask;
if ((sigprocmask(SIG_SETMASK, NULL, &retmask)) == -1)
printf("could not obtain process signal mask\n");
return retmask;
}
在我的程序开始时,我意识到过程信号掩码,没有阻止任何信号。然后我将信号处理程序放入程序中。
static void sig_abrt(int signo)
{
printf("Caught SIGABRT\n");
}
int main(void)
{
show_signals(getmask());
signal(SIGABRT, sig_abrt);
show_signals(getmask());
return 0;
}
所以现在有一个SIGABRT的信号处理程序,但如果我再次调用sigprocmask(2),如上所述,SIGABRT将不在进程信号掩码中。我尝试使用sigismember(3)进行检查,但只有在调用sigaddset(3)或其他修改信号掩码的函数后才会修改过程信号掩码。
如果我用sigaddset(3)阻止SIGABRT,信号处理程序sig_abrt在SIGABRT交付时是否会收到调用?这是否意味着信号掩码影响传递的信号?有什么区别?
另外,有没有办法在不使用sigsetops(3)和sigprocmask(2)函数的情况下阻止进程中的信号?