十七、Linux系统编程-信号(四)信号在内核中表示、信号的阻塞和未决

来源:互联网 发布:java中断机制 编辑:程序博客网 时间:2024/05/16 01:47
一、信号在内核中的表示
        执行信号的处理动作称为信号递达Delivery),信号从产生到递达之间的状态,称为信号未决Pending)。进程可以选择阻塞(Block)某个信号。被阻塞的信号产生时将保持在未决状态,直到进程解除对此信号的阻塞,才执行递达的动作。注意,阻塞和忽略是不同的,只要信号被阻塞就不会递达,而忽略是在递达之后可选的一种处理动作。信号在内核中的表示如下:


二、信号阻塞与未诀

三、信号集操作函数
(1)、信号集
函数声明:
#include <signal.h>int sigemptyset(sigset_t *set);//全部置0int sigfillset(sigset_t *set);//全部置1int sigaddset(sigset_t *set, int signum);//添加对应位int sigdelset(sigset_t *set, int signum);//删除对应位int sigismember(const sigset_t *set, int signum);//是否为1
函数参数:信号集,信号代码
返回值:成功返回0,失败返回-1

(2)、读取或更改进程的信号屏蔽字
函数声明:
#include <signal.h>int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
函数参数:改变方式,信号集,原来的信号集
返回值:成功返回0,失败返回-1并设置errno
 如果oset是非空指针,则读取进程的当前信号屏蔽字通过oset参数传出。如果set是非空指针,则更改进程的信号屏蔽字,参数how指示如何更改。如果osetset都是非空指针,则先将原来的信号屏蔽字备份到oset里,然后根据sethow参数更改信号屏蔽字。

示例:
#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <string.h>#include <stdio.h>#include <stdlib.h>#include <errno.h>#include <unistd.h>#include <signal.h>#define ERR_EXIT(m) \        do \        { \                perror(m); \                exit(EXIT_FAILURE); \        }while(0)void handle(int sig);void printsigset(sigset_t* set){        int i;        for (i=1;i < 64; ++i)        {                if (sigismember(set,i))                        putchar('1');                else                        putchar('0');        }        printf("\n");}int main(int argc,char* argv[]){        sigset_t pset;        sigset_t bset;        sigemptyset(&bset);        sigaddset(&bset,SIGINT);        if (signal(SIGINT,handle) == SIG_ERR)                ERR_EXIT("signal error");        if (signal(SIGQUIT,handle) == SIG_ERR)                ERR_EXIT("signal error");        sigprocmask(SIG_BLOCK,&bset,NULL);        for(;;)        {                sigpending(&pset);                printsigset(&pset);                sleep(1);        }        return 0;}void handle(int sig){        printf("recv a sig=%d\n",sig);        if (sig == SIGQUIT)        {                sigset_t uset;                sigemptyset(&uset);                sigaddset(&uset,SIGINT);                sigprocmask(SIG_UNBLOCK,&uset,NULL);        }}

0 0