《unix高级环境编程》信号——信号集
来源:互联网 发布:cdn是什么 知乎 编辑:程序博客网 时间:2024/05/18 09:42
信号集
信号集是表示多个信号的数据类型,这里的信号集数据类型是 sigset_t,包含五个处理信号集的函数:
/* 信号集 */#include <signal.h>int sigemptyset(sigset_t *set);//初始化由set所指向的信号集,清空信号集;int sigfillset(sigset_t *set);//初始化由set所指向的信号集,使其包括所有信号;int sigaddset(sigset_t *set, int signo);//把指定的信号signo添加到由set所指的信号集中;int sigdelset(sigset_t *set, int signo);//把指定的信号signo从由set所指定的信号集中删除;//前面四个函数返回值:若成功则返回0,若出错则返回-1;int sigismember(const sigset_t *set, int signo);//判断指定的信号signo是否在由set所指的信号集中;//返回值:若为真则返回1,若为假则返回0,若出错则返回-1;/* * 说明: * 所有应用程序使用信号集之前,要对该信号集调用sigemptyset或sigfillset一次; */
sigprocmask 函数
在前面我们提到,task_struct 结构有一个blocked 成员(我们称之为“信号屏蔽字”),它指定了进程阻塞的信号,被阻塞的信号将不能被递送给进程,直到进程解除阻塞。在信号被阻塞时,内核将其放置到待决列表上。如果同一个信号在阻塞期间被发送了多次,则在待决列表中只放置一次。也就是说,不管发送了多少相同的信号,在进程删除阻塞后,都只会接收到一个信号。调用函数sigprocmask可以检测或更改其信号屏蔽字。在调用 sigprocmask 后如果有任何未决的、不再阻塞的信号,则在sigprocmask 返回前,至少会将其中一个信号递送给该进程。
/* sigprocmask 函数 *//* * 函数功能:检查或更改信号屏蔽字,也可同时执行这两个操作; * 返回值:若成功则返回0,若出错则返回-1; * 函数原型: */#include <signal.h>int sigprocmask(int how, const sigset_t *set, sigset_t *oset);/* * 说明: * 若oset是非空指针,那么进程的当前信号屏蔽字通过oset返回; * 若set是非空指针,则参数how指示如何修改当前信号屏蔽字; * 若set是空指针,则不改变该进程的信号屏蔽字,how的值就没有意义; * 参数how可选以下值: * (1)SIG_BLOCK 该进程新的信号屏蔽字是其当前信号屏蔽字和set指向信号集的并集。set包含了我们希望阻塞的附加信号; * (2)SIG_UNBLOCK 该进程新的信号屏蔽字是其当前信号屏蔽字和set指向信号集补集的交集;set包含我们希望解除阻塞的附加信号; * (3)SIG_SETMASK 该进程新的信号屏蔽字将被set指向的信号集的值所代替; * SIG_BLOCK是"或"操作,而SIG_SETMASK则是赋值操作; * 注意:SIGKILL 和 SIGSTOP 信号是不能阻塞的; */
sigpending 函数
sigpending 函数返回信号集,其中的各个信号对于调用进程是阻塞的而不能传递,该信号集通过set参数返回。
/* sigpending函数 *//* * 函数功能:返回信号集; * 返回值:若成功则返回0,若出错则返回-1; * 函数原型: */#include <signal.h>int sigpending(sigset_t *set);
测试程序:
#include "apue.h"#include <sys/wait.h>#include <unistd.h>#include <sys/types.h>#include <errno.h>#include <signal.h>static void sig_quit(int signo);int main(){ sigset_t newmask,oldmask,pendmask; if(signal(SIGQUIT,sig_quit) == SIG_ERR) { err_sys("signal() error"); exit(-1); } //初始化信号集 sigemptyset(&newmask); //添加一个SIGQUIT信号 sigaddset(&newmask,SIGQUIT); //将newmask信号集设置为阻塞,原信号集保存在oldmask中 if(sigprocmask(SIG_BLOCK,&newmask,&oldmask) == -1) { err_sys("SIG_BLOCK error"); exit(-1); } sleep(5); //获取阻塞的信号集 if(sigpending(&pendmask) == -1) { err_sys("sigpending() error"); exit(-1); } //判断SIGQUIT是否是阻塞的 if(sigismember(&pendmask,SIGQUIT)) printf("\nSIGQUIT is pending.\n"); //恢复原始的信号集 if(sigprocmask(SIG_SETMASK,&oldmask,NULL) == -1) { err_sys("SIG_SETMASK error"); exit(-1); } printf("SITQUIT unblocked\n"); sleep(5); exit(0);}static void sig_quit(int signo){ printf("caught SIGQUIT.\n"); if(signal(SIGQUIT,SIG_DFL) == SIG_ERR) { err_sys("can't reset SIGQUIT"); exit(-1); }}输出结果:
$ ./sigset ^\SIGQUIT is pending.caught SIGQUIT.SITQUIT unblocked$ ./sigset ^\^\^\^\^\^\SIGQUIT is pending.caught SIGQUIT.SITQUIT unblocked在程序第二次 sleep 时,产生了多个SIGQUIT 信号,此时被pending,解除了 mask 后,只产生了一次action,也说明了在同一时刻产生多次同一种信号,不会对信号排队。
参考资料:
《UNIX高级环境编程》
0 0
- 《unix高级环境编程》信号——信号集
- 《unix高级环境编程》信号——信号集
- UNIX环境高级编程——信号
- UNIX环境高级编程——信号
- 《unix高级环境编程》信号——信号基本概述
- 《unix高级环境编程》信号——信号基本概述
- 《UNIX环境高级编程》笔记--信号集
- Unix高级环境编程(信号)
- Unix环境高级编程---信号
- UNIX环境高级编程——信号(API)
- UNIX环境高级编程——信号说明列表
- UNIX环境高级编程——线程和信号
- UNIX环境高级编程——信号1
- UNIX环境高级编程——信号2
- UNIX环境高级编程——线程和信号
- unix环境高级编程——线程同步信号
- 《unix环境高级编程》信号——sigaction 函数
- 《unix高级环境编程》信号——sigsuspend 函数
- 第一轮 C
- 一张图理解java注解
- [LeetCode]pow(double x,int n)解题报告
- DOM详解
- 递推-nyoj-The number of maximum subset
- 《unix高级环境编程》信号——信号集
- 10个我最喜欢问程序员的面试问题
- Matlab---寻找峰值函数
- 第十一周项目二(1)最大公约数
- 算不算被虚度的这几年
- 使用ActionSelector控制Action的选择
- Android开发~Android Studio环境篇(Mac环境)
- 第十一周项目二(2)求四个数最大公约数
- AJAX--初识