进程间通信--信号3(信号集)

2024-11-10  本文已影响0人  锈色的栅栏

1、信号集合的概述

在PCB中有两个非常重要的信号集。一个称之为“阻塞信号集”,另一个称之为“未决信号集”。 这两个信号集都是内核使用位图机制来实现的。但操作系统不允许我们直接对其进行位操作。而需自定义另外一个集合,借助信号集操作函数来对PCB中的这两个信号集进行修改

2、自定义信号集函数

sigset_t set,set即一个信号集。

#include<signal.h>
int sigemptyset(sigset_t *set); //将set集合置空
int sigfillset(sigset_t *set); //将所有信号加入set集合
int sigaddset(sigset_t *set, int signo); //将signo信号加入到set集合
int sigdelset(sigset_t *set, int signo); //从set集合中移除signo信号
int sigismember(const sigset_t*set,int signo);//判断信号是否存在

示例代码

#include<stdio.h>
#include<signal.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/time.h>
int main(int argc,char const*argv[]){
        //定义一个信号集合
        sigset_t set;

        //清空信号集合
        sigemptyset(&set);

        //将SIGINT 加入set集合
        sigaddset(&set, SIGINT);
        //将SIGISTP 加入set集合
        sigaddset(&set, SIGTSTP);
        
        //判断SIGINT是否在set中
        if (sigismember(&set, SIGINT))
        {
                printf("SIGINT在set集合中\n");
        }
        return 0;
}

3、信号屏蔽集(阻塞集)

信号阻塞集也称信号屏蔽集、信号掩码。每个进程都有一个阻塞集,创建子进程时子进程将继承父进程的阻塞集。
所谓阻塞并不是禁止传送信号, 而是暂缓信号的传送。

1.sigprocmask

#include<signal.h>
int sigprocmask(int how,const sigset_t *set,sigset_t *oldset);

功能:
        检查或修改信号阻塞集,根据 how 指定的方法对进程的阻塞集合进行修改,新的信号阻
        塞集由 set 指定,而原先的信号阻塞集合由 oldset 保存。
参数:
        how : 信号阻塞集合的修改方法,有 3 种情况:
                SIG_BLOCK:向信号阻塞集合中添加 set 信号集,新的信号掩码是set和旧信号掩码的并集
                相当于 mask = mask|set。
                SIG_UNBLOCK:从信号阻塞集合中删除 set 信号集,从当前信号掩码中去除 set 中
                的信号。相当于 mask = mask & ~ set。
                SIG_SETMASK:将信号阻塞集合设为 set 信号集,相当于原来信号阻塞集的内容清空,
                然后按照 set 中的信号重新设置信号阻塞集。相当于mask = set。
        set : 要操作的信号集地址。
            若 set 为 NULL,则不改变信号阻塞集合,函数只把当前信号阻塞集合保存到 oldset中。
        oldset : 保存原先信号阻塞集地址
返回值:
    成功:0,
    失败:-1,失败时错误代码只可能是 EINVAL,表示参数 how 不合法

示例代码

#include<stdio.h>
#include<signal.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/time.h>

int main(int argc,char const*argv[])
{
     //定义一个信号集合
     sigset_t set;

     //清空信号集合 
     sigemptyset(&set); 

     //将SIGINT 加入set集合
     sigaddset(&set, SIGINT); 

     //将set集合添加到阻塞集中
     sigprocmask(SIG_BLOCK, &set, NULL); 

     printf("5秒后SIGINT将从阻塞集中删除\n");
     sleep(5);
     //将set集合从阻塞集删除
     sigprocmask(SIG_UNBLOCK, &set, NULL);

     getchar();
     return 0;
}


2、sigpending函数

#include<signal.h>
int sigpending(sigset_t *set);

功能:
       读取当前进程的未决信号集
参数:
    set:未决信号集
返回值:
    成功:0
    失败:-1

示例代码

#include<stdio.h>
#include<signal.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/time.h>
int main(int argc,char const*argv[])
{
#if1
     //定义一个信号集合
     sigset_t set;
     //清空信号集合
     sigemptyset(&set);
     //将SIGINT 加入set集合
     sigaddset(&set, SIGINT);
    //将set集合添加到阻塞集中
     sigprocmask(SIG_BLOCK, &set, NULL);
     printf("5秒后判断SIGINT是否在未决信号集中\n");
     sleep(5); 
 #endif 
      sigset_t set2;
      sigemptyset(&set2);
      sigpending(&set2);
      if (sigismember(&set2, SIGINT))
      { 
          printf("SIGINT在未决信号集中\n"); 
      }
      //将set集合从阻塞集删除 
      sigprocmask(SIG_UNBLOCK, &set, NULL);
      return 0;
}

上一篇 下一篇

猜你喜欢

热点阅读