2023.08.17sigprocmask用法解析

  1. 实例一:配合signalfd使用
#include "head.h"
#include <sys/signalfd.h>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
 
#define handle_error(msg) \
    do { perror(msg); exit(EXIT_FAILURE); } while (0)
 
void handler(int a){
    printf("SIGINT handle fun %d\n", a);
    signal(SIGINT, handler);
}
int signal_test(void)
{
    sigset_t mask;
    int sfd;
    struct signalfd_siginfo fdsi;
    ssize_t s;
 
    sigemptyset(&mask);
    sigaddset(&mask, SIGINT);
    sigaddset(&mask, SIGQUIT);
 
    /* 阻塞信号以使得它们不被默认的处理试方式处理 */
 
    if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1)
        handle_error("sigprocmask");
 
    sfd = signalfd(-1, &mask, 0);
    if (sfd == -1)
        handle_error("signalfd");
    printf("modify signal\n");
    
    for (;;) {
        s = read(sfd, &fdsi, sizeof(struct signalfd_siginfo));
        if (s != sizeof(struct signalfd_siginfo))
            handle_error("read");
 
        if (fdsi.ssi_signo == SIGINT) {
            printf("Got SIGINT\n");

        } else if (fdsi.ssi_signo == SIGQUIT) {
            printf("Got SIGQUIT\n");
            exit(EXIT_SUCCESS);
        } else {
            printf("Read unexpected signal\n");
        }
    }
    return 0;
}
/*这个例子只是很简单的说明了使用signalfd的方法,并没有真正发挥它的作用,有了这个API,就可以将信号处理作为IO看待,
每一个信号集合(或者某一个对应的信号)就会有对应的文件描述符,这样将信号处理的流程大大简化,将应用程序中的业务作为文件来操作,也体现了linux下的一切皆文件
的说法,非常好,假如有很多种信号等待着处理,每一个信号描述符对待一种信号的处理,那么就可以将信号文件描述符设置为非阻塞,同时结合epoll使用,对信号的
处理转化为IO复用,和这个有相似之处的API还有timerfd*/

  sigprocmask的作用是将mask信号集的信号阻塞下来,不让其传递到进程信号处理函数中,这样做的目的是,能把信号传递给sfd,关联的文件描述符。这样就可以实现等待信号,有信号的时候就可以从sfd里读出信号并判断是哪个信号触发了,并作出相应的处理 。
实际输出:

modify signal
^CGot SIGINT
^CGot SIGINT
^CGot SIGINT
^\Got SIGQUIT
  1. 实例二:
#include "head.h"
#include <sys/signalfd.h>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
static void int_handler(int s)
{
    signal(SIGINT,int_handler);
    write(1,"!",1);
}
int test_sigprocmask()
{
    int i;
    sigset_t set;
    
    signal(SIGINT,int_handler);
    sigemptyset(&set);
    sigaddset(&set,SIGINT);//在空集合中添加int信号
    for(i=0;i<5;i++)
    {
        sigprocmask(SIG_BLOCK,&set,NULL);//在循环中阻塞int信号,之前的mask不关心,所以为null
        for(int j=0;j<5;j++)
        {
            write(1,"*",1);
            sleep(1);
        }
        write(1,"\n",1);
        sigprocmask(SIG_UNBLOCK,&set,NULL);
     }
    while(1)
    {
        puts("d");
        sleep(1);
    }
    // exit(0);
    return 0;
}

  这个实例是既有信号处理函数,又有阻塞,实现了信号的延时处理 ,主逻辑的工作不被打断,直到主逻辑处理完了才 解除阻塞信号,执行信号处理 函数。
实际输出:

***^C**
!**^C***
!*****
*****
***^C**
!d
d
d
d
^C!d
d
d
^\[1]    24764 quit       ./bin/hello
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值