信号屏蔽pending

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/centor/article/details/78436759

信号在内核中的表示:

  信号在传递过程中有三个状态:执行信号的处理动作称为信号递达(Delivery),信号从产生到递达之间的状态称为信号未决(Pending)。进程也可以选择阻塞(Block)某个信号,被阻塞的信号产生时将保持在未决状态,直到进程解除对此信号的阻塞,才执行递达动作。阻塞和忽略是不同的,只要信号被阻塞就不会递达,而忽略是在递达之后可选一种处理动作。信号在内核中的表示如下图所示:
这里写图片描述
  图中block表和pending表由位图形式存储信号状态,每个信号只有一bit的未决标志,非0即1,不记录该信号产生了多少次,阻塞标志也是这样表示的。因此,未决和阻塞标志可以用相同的数据类型sigset_t储,sigset_t称为信号集,这个类型可以表示每个信号的“有效”或“无效”状态,在阻塞信号集中“有效”和“无效”的含义是该信号是否被阻塞,而在未决信号集中“有效”和“无效”的含义是该信号是否处于未决状态。阻塞信号集也叫做当前进程的信号屏蔽字(Signal Mask),这的“屏蔽”应该理解为阻塞而不是忽略。

信号处理函数:

int sigemptyset(sigset_t *set);
//初始化set所指向的信号集,使其中所有信号的对应bit清零,表示该信号集不包含任何有效信号 
int sigfillset(sigset_t *set);
//t初始化set所指向的信号集,使其中所有信号的对应bit置位有效,表示该信号集的有效信号包括系统支持的所有信号 
int sigaddset(sigset_t *set, int signo);
//信号集中添加某种有效信号 
int sigdelset(sigset_t *set, int signo);
//信号集中删除某种有效信号
int sigismember(const sigset_t *set, int signo); 
//用于判断一个信号集的有效信号中是否包含某种信号
调用函数sigprocmask可以读取或更改进程的信号屏蔽字(阻塞信号集)。 
int sigprocmask(int how, const sigset_t *set, sigset_t *oset); 
返回值:若成功则为0,若出错则为-1 
how参数: 
1)SIG_BLOCK添加到当前信号屏蔽字的信号 
2)SIG_UNBLOCK从当前信号屏蔽字中解除的信号 
3)SIG_SETMASK设置当前信号屏蔽字为set所指向的值 
int sigpending(sigset_t *set);
//sigpending读取当前进程的未决信号集,通过set参数传出。调⽤用成功则返回0,出错则返回 -1

验证pending表,修改pcb的pending表中的一个bit位,即发信号,下面这段代码中为Ctrl+c信号

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

void handler(int s)
{
    if(s==SIGINT)
    {

    }else if(s==SIGQUIT)
    {
        sigset_t set;
        sigemptyset(&set);
        sigaddset(&set, SIGINT);
        sigprocmask(SIG_UNBLOCK, &set, NULL);
    }
}

void print_set(sigset_t *set)
{
    int i;
    for(i=1; i<NSIG; i++)
    {
        if(sigismember(set,i))
        {
            printf("1");
        }
        else
        {
            printf("0");
        }
    }
    printf("\n");
}
int main()
{
    signal(SIGINT, handler);
    signal(SIGQUIT, handler);
    sigset_t bset,pset;
    sigemptyset(&bset);//清空信号集
    sigaddset(&bset, SIGINT);//将int信号加入信号集
    sigprocmask(SIG_BLOCK, &bset, NULL);//将我们的值设置进内核

    for(;;)
    {
        sigpending(&pset);//获得内核的未决信号集
        print_set(&pset);
        sleep(1);
    }
}

这里写图片描述

猜你喜欢

转载自blog.csdn.net/centor/article/details/78436759