UNIX环境高级编程》的信号部分这一章介绍了信号集和信号屏蔽字的概念,信号集中记录了内核不许发生的信号,由于信号数量可能会超过一个整数所包含位数,因此定义了sigset_t类型来包含一个信号集(以下代码注释中为了方便起见,使用了八位的屏蔽字表示一个信号集)。与信号集相关的函数包括了sigemptyset、sigfillset、sigprocmask等。以下通过书上的一段程序对这些函数进行解释。
#include
#include
#include
static void sig_quit(int);
void error(char *);
int main(void)
{
假设当前进程屏蔽字为11011000,SIGQUIT屏蔽字为00100000
sigset_t newmask, oldmask, pendmask; /声明三个信号集
if(signal(SIGQUIT, sig_quit) == SIG_ERR) 捕捉ctrl+\产生的信号,然后执行sig_quit信号执行程序
printf("signal error\n");
sigemptyset(&newmask); 初始化newmask为00000000
sigaddset(&newmask, SIGQUIT); 将SIGQUIT添加到newmask信号集,此时newmask为00100000
if(sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0) 将当前进程屏蔽字与newmask取并集,使得进程屏蔽字变成11111000,并且将进程原来的屏蔽字11011000保存在oldmask中
error("mask error");
sleep(5);
if(sigpending(&pendmask) < 0) 返回当前信号屏蔽子11111000,保存在pendmask中
error("pending error");
if(sigismember(&pendmask, SIGQUIT)) 检查pendmask信号集是否屏蔽SIGQUIT信号
printf("\nSIGQUIT pending\n");
if(sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0) 将原信号集oldmask(11011000)设置为当前进程的信号屏蔽字
error("SIG_SETMASK error");
printf("\nSIGQUIT unblocked\n");
sleep(5);
exit(0);
}
static void sig_quit(int signo)
{
printf("caught SIGQUIT\n");
if(signal(SIGQUIT, SIG_DFL) == SIG_ERR) 当程序捕捉到SIGQUIT时,执行默认操作,即终止+core
error("can't reset SIGQUIT");
}
void error(char *arr)
{
printf("the error is %s\n", arr);
}
阅读(1393) | 评论(0) | 转发(0) |