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调用,直到收到信号。这个时候进程可能进入信号处理函数,也可能直接终止。

sigpendingsigprocmask就可以对某些信号进行屏蔽。

为了查看当前哪些信号被屏蔽,引入了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();

设置之后,除了屏蔽字中的信号,其他信号都能收到,此时要么进入信号处理函数,要么程序直接终止。

下面一段代码将测试sigprocmasksigpending函数,完整代码: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
原创粉丝点击