Linux 信号(二)信号集
来源:互联网 发布:游戏美工培训学费 编辑:程序博客网 时间:2024/05/19 11:49
信号集
信号集可以用来表示一组信号,用sigprocmask
系列函数可以让应用程序对一些信号进行屏蔽。
类似于select
调用中的fd_set
一个信号对应一个比特位。
在信号中,这样的数据结构用sigsetg_t
表示。
#include <signal.h>int sigemptyset(sigset_t *set); //初始化set指向的信号集,使其为空int sigfillset(sigset_t *set); //初始化set指向的信号集,使其包含所有信号int sigaddset(sigset_t *set, int signum); // 添加一个信号int sigdelset(sigset_t *set, int signum); //删除一个信号int sigismember(const sigset_t *set, int signum);//测试指定位
回忆pause()
函数:
pause() causes the calling process (or thread) to sleep until a signalis delivered that either terminates the process or causes the invoca‐tion of a signal-catching function.
进程阻塞在pause
调用,直到收到信号。这个时候进程可能进入信号处理函数,也可能直接终止。
而sigpending
和sigprocmask
就可以对某些信号进行屏蔽。
为了查看当前哪些信号被屏蔽,引入了apue中的一个库函数:
核心思想就是利用sigismember
查看信号是否在屏蔽信号集中
voidpr_mask(const char *str){ sigset_t sigset; int errno_save; errno_save = errno; /* we can be called by signal handlers */ if (sigprocmask(0, NULL, &sigset) < 0) {//获取当前oldset err_ret("sigprocmask error"); } else { printf("%s", str); if (sigismember(&sigset, SIGINT)) printf(" SIGINT"); if (sigismember(&sigset, SIGQUIT)) printf(" SIGQUIT"); if (sigismember(&sigset, SIGUSR1)) printf(" SIGUSR1"); if (sigismember(&sigset, SIGALRM)) printf(" SIGALRM"); /* remaining signals can go here */ printf("\n"); } errno = errno_save; /* restore errno */}
上文提到的sigprocmask
函数
#include <signal.h>int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
第一个参数表示取值有三个:
SIG_BLOCK:屏蔽信号,添加的信号屏蔽字不覆盖之前的,这是一个并集的关系
SIG_UNBLOCK:希望解除BLOCK的信号集合。
SIG_SETMASK:该进程的信号屏蔽是set指向的值。
注意到这里后两个参数,set
用以设置新的信号屏蔽字,oldset
返回当前信号屏蔽字。
如果不进行设置,仅仅只是想得到当前的信号屏蔽字,那么前两个参数也就没有意义了。
sigprocmask(0,NULL,&sigset);
sigprocmask
仅仅是对屏蔽字进行设置,程序将继续执行,sigpending
将设置屏蔽字,同时阻塞。
就像执行了两步操作:
//第一步sigprocmask();//第二步pause();
设置之后,除了屏蔽字中的信号,其他信号都能收到,此时要么进入信号处理函数,要么程序直接终止。
下面一段代码将测试sigprocmask
和sigpending
函数,完整代码:github
可以用kill -[信号] [pid]
进行测试
#include <stdio.h>#include <stdlib.h>#include <assert.h>#include <unistd.h>#include <sys/time.h>#include <malloc.h>#include <signal.h> static voidsig_int(int signo){ pr_mask("\nin sig_int: ");} static voidsig_quit(int signo){ pr_mask("\nin sig_quit: ");}int main(int argc,char **argv){ sigset_t newmask, oldmask, waitmask; pr_mask("program start: "); if (signal(SIGINT, sig_int) == SIG_ERR) err_sys("signal(SIGINT) error"); if(signal(SIGQUIT,sig_quit)==SIG_ERR) err_sys("signal(SIGQUIT) error"); //init to zero sigemptyset(&waitmask); //add SIGUSR1 sigaddset(&waitmask, SIGUSR1); //init to zero sigemptyset(&newmask); //add SIGINT sigaddset(&newmask, SIGINT); //BLOCK SIGINT and save current sigsets if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0) err_sys("SIG_BLOCK error");// sleep(10);//will not receive SIGINT#if 1 /* * Critical region of code. */ pr_mask("in critical region: "); /* * Pause, allowing all signals except SIGUSR1. */ if (sigsuspend(&waitmask) != -1) err_sys("sigsuspend error"); pr_mask("after return from sigsuspend: "); /* * Reset signal mask which unblocks SIGINT. */ if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0) err_sys("SIG_SETMASK error"); /* * And continue processing ... */ pr_mask("program exit: ");#endif return 0;}
PS: 在终端输入kill -l
可以查看各个信号对应的编号:
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR213) SIGPIPE 14) SIGALRM 15) SIGTERM 16) SIGSTKFLT17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU25) SIGXFSZ 26) SIGVTALRM 27) SIGPROF 28) SIGWINCH29) SIGIO 30) SIGPWR 31) SIGSYS 34) SIGRTMIN35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3 38) SIGRTMIN+439) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+843) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+1247) SIGRTMIN+13 48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-1451) SIGRTMAX-13 52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-1055) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7 58) SIGRTMAX-659) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-263) SIGRTMAX-1 64) SIGRTMAX
阅读全文
1 0
- Linux 信号(二)信号集
- linux 信号 信号集
- linux 信号列表 (二)
- Linux 信号机制 (二)
- Linux 信号理解(二)
- Linux-信号(二)pending
- Linux系统编程--信号及信号处理(二)
- Linux下的信号(二)----阻塞信号
- Linux入门:信号(二)——阻塞信号
- Linux 信号和信号集
- Linux 信号和信号集
- 十五、Linux系统编程-信号(二)信号分类、可靠信号与不可靠信号、信号发送 pause
- linux信号signal处理机制(二)
- Linux-信号机制详解(二)
- Linux信号(二)-- signal()函数
- 信号浅析(二)
- 信号(二)
- Linux下的信号(二)
- APK瘦身
- binder学习概述篇和路线图
- JS函数
- 算法作业_38(2017.6.20第十八周)
- Swift15-闭包
- Linux 信号(二)信号集
- ###django 不依赖工程执行orm操作
- github常见操作和常见错误!错误提示:fatal: remote origin already exists.
- android选择城市三级联动
- JAVA中的数据存储(堆及堆栈)
- ROC和AUC介绍以及如何计算AUC F
- yii中cookie的使用
- 把json格式数据写入到本地文件
- 简书用户名爬取