zoukankan      html  css  js  c++  java
  • PCB信号集

    每一个进程都有一个pcb进程控制块,用来控制进程的信息,同时信号在pcb中有两个队列去维护他,一个是未决信号集,每一位对应一个信号的状态,0,1,1表示未决态,另一个是信号屏蔽字(阻塞信号集),也就0,1(1代表阻塞),

    用户可以改变阻塞信号集的状态,但是改变不了未决信号集的状态

    进程在接触对某个信号的阻塞之前,如果再次接受一个甚至多个信号,常规信号在递达态之前只会留下一个信号,使其处于未决态,而对于实时信号,会产生一个队列与存储,每一个信号只有一个bit,非0就是1,只表示有么有,不表示多少个。

    阻塞信号集的设计过程:

    一般的操作流程是先构造sigset_t信号集,通过以下函数操作信号集

    1 sigset_t为信号集,可sizeof(sigset_t)察看其大小为128个字节
    2 
    3 以下是对信号集的操作:
    4 int sigemptyset(sigset_t *set)      清空某个信号集(全置0)
    5 int sigfillset(sigset_t *set)       阻塞所有信号(全置1  )
    6 int sigaddset(sigset_t *set, int signo)     将信号集的signo位值1,即阻塞该信号
    7 int sigdelset(sigset_t *set, int signo)     将信号集的signo位值0,即不阻塞该信号
    8 int sigismember(const sigset_t *set, int signo)     测试signo的信号位为1还是0

    然后使用以sigprocmask函数注册到系统的阻塞信号集中使其生效:

    1、sigprocmask

      调用函数sigprocmask可以读取更改进程的信号屏蔽字。

    1 #include <signal.h>
    2 
    3 int sigprocmask(int how, const sigset_t *set, sigset_t *oset);
    4 
    5 返回值:若成功则为0,若出错则为-1

    (1)如果oset是非空指针,则读取进程的当前信号屏蔽字通过oset参数传出。

    (2)如果set是非空指针,则更改进程的信号屏蔽字,参数how指示如何更改。(

    3)如果oset和set都是非空指针,则先将原来的信号屏蔽字备份到oset里,然后根据set和how参数更改信号屏蔽字。假设当前的信号屏蔽字为mask,下表说明了how参数的可选值

    1 SIG_BLOCK   set包含了我们希望添加到当前信号屏蔽字的信号,相当于mask=mask|set
    2 SIG_UNBLOCK  set包含了我们希望从当前信号屏蔽字中解除阻塞的信号,相当于mask=mask&~set
    3 SIG_SETMASK  设置当前信号屏蔽字为set所指向的值,相当于mask=set
     1 /*
     2  *程序运行时,每秒钟把各信号的未决状态打印一遍,由于我们阻塞了SIGINT信号,
     3  *按Ctrl-C将会使SIGINT信号处于未决状态,
     4  *按Ctrl-仍然可以终止程序,因为SIGQUIT信号没有阻塞。
     5  *
     6  *book@ubuntu:~$ ./app
     7  *0000000000000000000000000000000
     8  *0000000000000000000000000000000(这时按Ctrl-C)
     9  *0100000000000000000000000000000
    10  *0100000000000000000000000000000(这时按Ctrl-)
    11  *Quit (core dumped)
    12  *
    13  *或者按下Ctrl-C十秒之后也会推出,这就是main函数中的while中的代码的作用
    14  */
    15 #include <signal.h>
    16 #include <stdio.h>
    17 void printsigset(const sigset_t *set)
    18 {
    19     int i;
    20     for (i = 1; i < 32; i++)//从1号信号开始检测
    21         if (sigismember(set, i) == 1)//测试i号位知否置1
    22             putchar('1');
    23         else
    24             putchar('0');
    25     puts("");//打印换行
    26 }
    27 int main(void)
    28 {
    29     int i = 0;
    30     sigset_t s, p;  //定义两个信号集  每一个信号集的大小是128Byte
    31     sigemptyset(&s);//将信号集s全部信号位置0
    32     sigaddset(&s, SIGINT);//将s信号集中的SIGINT信号位(即2号位)置1
    33 
    34     sigprocmask(SIG_BLOCK, &s, NULL);//将s信号集合原有信号集做或操作(由第一个参数决定更改方式)
    35     while (1)
    36     {
    37         sigpending(&p);//获取当前进程未决信号集
    38         printsigset(&p);//打印未决信号集
    39 
    40         if(i == 10)//10秒后释放对SIGINT信号的阻塞
    41         {
    42             sigprocmask(SIG_UNBLOCK, &s, NULL);
    43         }
    44         sleep(1);
    45         i++;
    46     }
    47     return 0;
    48 }

    2、sigpending

    sigpending读取当前进程的未决信号集,通过set参数传出。调用成功则返回0,出错则返回-1。

  • 相关阅读:
    word-spacing汉字不起作用的解决方法
    FontAwesome 4.4.0 中完整的585个图标样式CSS参考
    margin-top失效的解决方法
    今天有群友不是很清楚htm直接存数据库的危害,我简单举个例子
    前端:图文混排-怎么在不使用float的情况下实现想要的效果呢?
    前端:圆图头像制作--border-radius : 100%
    样式问题-如何一次性设置网站英文字体样式,中文字体等样式
    8.GitHub实战系列~8.使用GitHub建立自己的免费博客
    牛逼的OSQL----大数据导入
    01.SQLServer性能优化之----强大的文件组----分盘存储
  • 原文地址:https://www.cnblogs.com/13224ACMer/p/6408023.html
Copyright © 2011-2022 走看看