您的位置:首页 > 其它

sigprocmask阻塞信号

2018-02-07 16:06 483 查看
int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);

参数的how:

SIG_BLOCK :附加set到阻塞表,原来的保存在到oldset

SIG_UNBLOCK:从阻塞表中删除set中的信号,原来的保存到oldset

SIG_SETMASK:清空阻塞表并设置为set,原来的保存到oldset

假设现在阻塞的信号表是{SIGSEGV,SIGSUSP},我们执行了以下代码:

sigset_t x,y;

sigemtyset(&x);

sigemtyset(&y);

sigaddset(&x,SIGUSR1);

sigprocmask(SIG_BLOCK,&x,&y);

则新的阻塞表是{SIGSEGV,SIGSUSP,SIGUSR1},y中保存的是{SIGSEGV,SIGSUSP}

如果我接着执行sigprocmask(SIG_UNBLOCK,&x,NULL),

则新的阻塞表是{SIGSEGV,SIGSUSP}

如果我接着执行sigprocmask(SIG_SETMASK,&x,NULL);

则新的阻塞表是{SIGUSR1}。

返回说明:

成 功执行时,返回0。失败返回 - 1 ,errno被设为EINVAL。

代码:

#include<stdio.h>

#include<signal.h>

#include<stdlib.h>

#include<sys/types.h>

void handler(int sig)

{

    printf("get a sig,num is:%d\n",sig);

}

void print_sig(sigset_t *p)

{

    int i = 1;

    for(;i < 32;++i){

        if(sigismember(p,i)){//信号集p中是否有信号i.

            printf("1");

        }else{

            printf("0");

        }

    }

    printf("\n");

}

int main()

{

    signal(2,handler);//当接收到2(SIGINT,CTRL+C)信号,就执行handler函数

    sigset_t s,p,o;//设置信号集

    sigemptyset(&s);//清空信号集

    sigemptyset(&o);

    sigaddset(&s,SIGINT);//往信号集s中添加信号SIGINT

    sigprocmask(SIG_SETMASK,&s,&o);
//SIG_SETMASK:清空阻塞表并设置为s,原来的保存到o中

    int count = 0;

    while(1){

        sigemptyset(&p);

        sigpending(&p);//获取当前进程信号发生位图,即获取当前进程中所有信号放入信号集p中.

        print_sig(&p);

        sleep(1);

        if( count++ == 10 ){

            sigprocmask(SIG_SETMASK,&o,NULL);

            printf("recover block\n");

            sleep(3);

        }

    }

}

代码2:

#include

#include

#include

#include

#include

int main(){

sigset_t initset;

int i;

sigemptyset(&initset);//初始化信号集合为空集合

sigaddset(&initset,SIGINT);//将SIGINT信号加入到此集合中去

while(1){

sigprocmask(SIG_BLOCK,&initset,NULL);//将信号集合加入到进程的阻塞集合中去

fprintf(stdout,"SIGINT singal blocked/n");

for(i=0;i<10;i++){

sleep(1);//每1秒输出

fprintf(stdout,"block %d/n",i);

}

//在这时按一下Ctrl+C不会终止

sigprocmask(SIG_UNBLOCK,&initset,NULL);//从进程的阻塞集合中去删除信号集合

fprintf(stdout,"SIGINT SINGAL unblokced/n");

for(i=0;i<10;i++){

sleep(1);

fprintf(stdout,"unblock %d/n",i);

}

}

exit(0);

}

 

执行结果:

SIGINT singal blocked

block 0

block 1

block 2

block 3

block 4

block 5

block 6

block 7

block 8

block 9

在执行到block 3时按下了CTRL+C并不会终止,直到执行到block9后将集合从阻塞集合中移除。

[root@localhost C]# ./s1

SIGINT singal blocked

block 0

block 1

block 2

block 3

block 4

block 5

block 6

block 7

block 8

block 9

SIGINT SINGAL unblokced

unblock 0

unblock 1

由于此时已经解除了阻塞,在unblock1后按下CTRL+C则立即终止。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: