zoukankan      html  css  js  c++  java
  • Linux—信号阻塞与信号未决(day10)

    目录

    一、信号阻塞与信号未决

    二、pause(2)的使用

    三、信号传送过程处理

    四、可重入函数

    五、编写代码实现信号处理函数的继承

    六、setitimer实现定时器


    一、信号阻塞与信号未决

      进程可以对某个信号设置阻塞或屏蔽,可是使用sigset_t(信号集)这个数据类型进行操作,对sigset_t操作的函数函数:

      int sigemptyset(sigset_t *set);
      int sigfillset(sigset_t *set);
      int sigaddset(sigset_t *set, int signum);
      int sigdelset(sigset_t *set, int signum);
      int sigismember(const sigset_t *set, int signum);
      int sigaction( int sig, const struct sigaction *act,struct sigaction *oact );
      
      各个函数对应的功能如下:
      sigemptyset(sigset_t *set)初始化由set指定的信号集,信号集里面的所有信号被清空;
      sigfillset(sigset_t *set)调用该函数后,set指向的信号集中将包含linux支持的64种信号;
      sigaddset(sigset_t *set, int signum)在set指向的信号集中加入signum信号;
      sigdelset(sigset_t *set, int signum)在set指向的信号集中删除signum信号;
      sigismember(const sigset_t *set, int signum)判定信号signum是否在set指向的信号集中。
      int sigaction( int sig, const struct sigaction *act,struct sigaction *oact )检查、修改和指定信号相关联的信号响应。
     
    sigset操作函数
     
    #include<signal.h> 
     
     
    int sigemptyset(sigset_t *set);
    功能:
      将信号集清空
    参数:
      指定要清空的信号集
    返回值:
      成功:0
      错误:-1
     
     
    sigfillset(sigset_t *set)
    功能:
      将信号集置为满
    参数:
       set:指定要置满的信号集
    返回值:
     
      成功:0
      错误:-1
     
     
    int sigaddset(sigset_t *set, int signum);
    功能:
      给信号集添加信号
    参数:
       set:指定信号集
      signum:指定添加信号
    返回值:
      成功:0
      错误:-1
     
     
      int sigdelset(sigset_t *set, int signum);
    功能:
      删除指定信号
    参数:
       set:指定信号集
      signum:指定删除信号
    返回值:
      成功:0
      错误:-1
     
     
    int sigismember(const sigset_t *set, int signum);
    功能:
      测试信号是否为指定信号集成员
    参数:
       set:指定信号集
      signum:指定信号
    返回值:
      错误:-1
      否:0
      有:1
     

    设置解除阻塞
      设置对2号信号进行阻塞:
    1、定义sigset_t block_set信号集
    2、将block_set信号集所有成员清空
    3、将2号信号添加到block_set信号集中
    4、将block_set设置为这个进程的阻塞信号集
    如何将信号集设置为阻塞:使用sigprocmask(2)函数,包含头文件#include <signal.h>     。

    执行信号的处理动作称为信号递达(Delivery),信号从产生到递达之间的状态,称为信号未决(Pending)。

    进程可以选择阻塞(Block)某个信号。被阻塞的信号产生时将保持在未决状态,直到进程解除对此信号的阻塞,才执行递达的动作。注意,阻塞和忽略是不同,只要信号被阻塞就不会递达,而忽略是在递达之后可选的一种处理动作。

             
    int sigprocmask(int how,const sigset_t*set,sigset_t *oldset);   
    功能:
      检测活泼改变阻塞信号
    参数:
         how:用于指定信号修改的方式,可能选择有三种

           SIG_BLOCK//将set所指向的信号集中包含的信号加到当前的信号掩码中。即信号掩码和set信号集进行或操作。

                SIG_UNBLOCK//将set所指向的信号集中包含的信号从当前的信号掩码中删除。即信号掩码和set进行与操作。

           SIG_SETMASK //将set的值设定为新的进程信号掩码。即set对信号掩码进行了赋值操作。

        set:为指向信号集的指针,在此专指新设的信号集,如果仅想读取现在的屏蔽值,可将其置为NULL。

        oldset:也是指向信号集的指针,在此存放原来的信号集。可用来检测信号掩码中存在什么信号。


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

    例:实现对2号信号的阻塞
    #include<stdio.h>
    #include<signal.h>
    
    int main(void){
        signal_t block;
        //将block集合清空
        sigemptyset(&block);
        //将2号信号添加到block集合中
        sigaddset(&block,SIGINT);
        //将block设置为阻塞信号集
        sigprocmask(SIG_SETMASK,&block,NULL);
        while(1);
        return 0;
    } 

     1、对阻塞信号解除

      信号可以分为可靠信号和不可靠信号,多个相同的不可靠信号(1-31),只会响应一个,其他会丢失。可靠信号(34-64)的每一信号都会被响应。

    #include<stdio.h>
    #include<signal.h>
    
    int main(void){
        signal_t block;
        //将block集合清空
        sigemptyset(&block);
        //将2号信号添加到block集合中
        sigaddset(&block,SIGINT);//此处为不可靠信号
        //将block设置为阻塞信号集
        sigprocmask(SIG_SETMASK,&block,NULL);
        sleep(10);
        sigprocmask(SIG_UNBLOCK,&block,NULL);
        return 0;
    } 

     2、信号阻塞,查看未决信号

    使用sigpending(2)查看
    sigpending(2)
    #include<signal.h>
    int sigpending(sigset_t set);
    功能:
      检测未决信号
    参数:
      set:值-结果参数,用于返回进程的未决信号
    返回值:
      成功:0
      错误:-1
    例,检测未决信号
    #include<stdio.h>
    #include<signal.h>
    
    int main(void){
        signal_t b,p;
        //将b集合清空
        sigemptyset(&b);
        //将2号信号添加到b集合中
        sigaddset(&b,SIGINT);//此处为不可靠信号
        //将b设置为阻塞信号集
        sigprocmask(SIG_SETMASK,&b,NULL);
        while(1){
            sleep(1);
            sigemptyset(&p);
            sigpending(&p)
            //检测信号
            int f=sigismember(&p,2);
            if(f==-1){
                perror("sigismember");
                return 1; 
            }
            if(f==0){
                printf("no 2
    ");
            }else{
                printf("pending 2
    ");
            }
        }
        return 0;
    }     
    int sigsuspend(const sigset_t*sigmask);

    五、编写代码实现信号处理函数的继承

    略,子进程可以继承父进程的信号处理函数。
     
     
     
  • 相关阅读:
    UVAlive3708 UVA1388 POJ3154 Graveyard【水题】
    UVALive5520 UVA305 POJ1012 HDU1443 Joseph【数学计算+打表】
    Go语言的素数对象编程实现及其使用
    Go语言实现的素数筛选程序
    Go语言的map以及sort
    封装统一数据验证方法
    项目开发中发布更新文档备注
    Asp.net Web Api开发Help Page 添加对数据模型生成注释的配置和扩展
    编写一个通用递归获取树形结构对象集合的方法
    使用AutoFac实现依赖注入(封装一个注册类)
  • 原文地址:https://www.cnblogs.com/ptfe/p/11020493.html
Copyright © 2011-2022 走看看