Linux signals(二) sigprocmask,sigaction,不可靠信号及实例代码

6 篇文章 0 订阅

简单举例sigpromask

#include<stdio.h>
#include<signal.h>
#include<unistd.h>
#include<string.h>

void handler(int sig);

void printsigset(sigset_t *set)
{
    int i;
    for(i=1;i<NSIG;++i)//NSIG是LINUX规定信号量总数
    {
        if(sigismember(set,i))//判断某一信号是否在给定集合中
            putchar('1');
        else
            putchar('0');
    }
    printf("\n");
}

int main(int argc,char *argv[])
{
    sigset_t pset;
    sigset_t bset;
    //类似于memset一样的初始化工作
    sigemptyset(&bset);
    sigaddset(&bset,SIGINT);
    if(signal(SIGINT,handler)==SIG_ERR)
        perror("signal error");
    if(signal(SIGQUIT,handler)==SIG_ERR)
        perror("signal error");
    //将SIGINT置为阻塞状态
    sigprocmask(SIG_BLOCK,&bset,NULL);

    for(;;)
    {
        //返回当前所有被挂起的信号
        sigpending(&pset);
        printsigset(&pset);
        sleep(1);
    }
    return 0;

}

void handler(int sig)
{
    if(sig==SIGINT)
     printf("recv a sig = %d\n",sig);
    else if(sig==SIGQUIT)
    {
        sigset_t uset;
        sigemptyset(&uset);
        sigaddset(&uset,SIGINT);
        //将SIGINT信号置成非阻塞状态
        sigprocmask(SIG_UNBLOCK,&uset,NULL);
    }
}

执行结果:

[root@izwz9j36enzsqqima735r4z cprograms]# ./sigset01 
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
//按ctrl+c
^C0100000000000000000000000000000000000000000000000000000000000000
0100000000000000000000000000000000000000000000000000000000000000
0100000000000000000000000000000000000000000000000000000000000000
0100000000000000000000000000000000000000000000000000000000000000
0100000000000000000000000000000000000000000000000000000000000000
//在另一个终端  ps aux
//执行 #kill -QUIT 11651
//当前终端
recv a sig = 2
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
//再按ctrl+c
^C0100000000000000000000000000000000000000000000000000000000000000
0100000000000000000000000000000000000000000000000000000000000000
//使进程终止
^Z
[1]+  已停止               ./sigset01
  • 一定要注意的是,一开始输出显示2号信号并不是pending状态,
    因为即使一开始设置为了block,但由于还没有发送信号,因此并没有任何一个信号处于pending状态

sigaction以及不可靠信号举例

#include<stdio.h>
#include<signal.h>
#include<unistd.h>
#include<string.h>

void handler(int sig);

int main(void)
{
    struct sigaction act;
    act.sa_handler=handler;
    sigemptyset(&act.sa_mask);
    act.sa_flags=0;
    if(sigaction(SIGINT,&act,NULL)<0)
    {
        perror("error");
    }
    for(;;)
    //使进程处于挂起状态,这样能尽可能小的占用cpu资源,又能接受信号
        pause();
    return 0;
}

void handler(int sig)
{
    printf("recv a sig=%d\n",sig);
    int n=30;
    do
    {
        /*注意,这儿一定得这样写,因为进程被唤醒时,sleep会直接返  回,返回值就是还剩下的睡眠时间*/
        n=sleep(n);
    }while(n>0);
}

测试结果:

先运行
 #./sigaction
//按ctrl+c,处理函数输出
^Crecv a sig=2
//处理函数处于睡眠状态,此时再按ctrl+c没反应
//不可靠信号就体现在这儿,此时无论发送了多少了信号,都只会保留一个
//因此能看到的结果是,30s过后,只打印输出一次,
//再等下一个30s到来,也没有第二次的打印输出了
^C^C^C^Crecv a sig=2
^Z
[1]+  已停止               ./sigaction
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值