linux信号--阻塞与未决

摘要:
执行信号的处理动作称为信号传递,信号从产生到传递的状态称为信号未决。该过程可以选择阻止信号。注意,阻塞和忽略是不同的。只要信号被阻断,它就不会被传送。忽略是交付后的可选处理操作。);这是信号设计机制。

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

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

linux信号--阻塞与未决第1张

1:PCB进程控制块中函数有信号屏蔽状态字(block)信号未决状态字(pending)还有是否忽略标志(或是信号处理函数);block状态字、pending状态字 64bit;

2:信号屏蔽状态字(block),1代表阻塞、0代表不阻塞;信号未决状态字(pending)的1代表未决,0代表信号可以抵达了;它们都是每一个bit代表一个信号,比如,bit0代表信号SIGHUP;

3:比如向进程发送SIGINT,内核首先判断信号屏蔽状态字是否阻塞,如果该信号被设为为了阻塞的,那么信号未决状态字(pending)相应位制成1;若该信号阻塞解除,信号未决状态字(pending)相应位制成0;表示信号此时可以抵达了,也就是可以接收该信号了。

 4:屏蔽状态字用户可以读写,未决状态字用户只能读(?);这是信号设计机制。

信号集操作函数,对状态字进行操作(屏蔽状态字和未决状态字):

#include <signal.h>
int sigemptyset(sigset_t *set);//将信号集清空,共64bits
int sigfillset(sigset_t *set);//将信号集置1
int sigaddset(sigset_t *set, int signum);//将signum对应的位置为1
int sigdelset(sigset_t *set, int signum);//将signum对应的位置为0
int sigismember(const sigset_t *set, int signum);//判断signum是否在该信号集合中,如果集合中该位为1,则返回1,表示位于在集合中
还有一个函数可以读取更改屏蔽状态字的API函数

 #include <signal.h>

int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);

参数how有下面三种取值:
SIG_BLOCK:  将参数set指向的信号集中设置的信号添加到现在的屏蔽状态字中,设置为阻塞;
SIG_UNBLOCK:将参数set指向的信号集中设置的信号添加到现在的屏蔽状态字中,设置为非阻塞, 也就是解除阻塞;
SIG_SETMASK:将参数set指向的信号集直接覆盖现在的屏蔽状态字的值;
如果oset是非空指针,则读取进程的当前信号屏蔽字通过oset参数传出。
若成功则为0,若出错则为-1

还有一个函数可以读取未决状态字(pending)信息 
#include <signal.h>
int sigpending(sigset_t *set);
SIGINT信号设置阻塞,查看未决关键字 
发送SIGINT信号,查看未决关键字 
发送SIGQUIT信号解除SIGINT信号阻塞,查看未决关键字 

刚开始设置SIGINT信号为阻塞信号,当按下Ctrl+c发送中断信号SIGINT(值为2,所以后来第二位被置1)之前,未决状态字的所有位都是0,因为此时没有未抵达的信号;
当发送SIGINT信号后,因为该信号是阻塞的,所以未决状态字将第二位置为了1,表示该信号在这里阻塞了;当我按下Ctrl+发送SIGQUIT信号后,又将SIGINT信号设置为了非阻塞的;
此时可以看到未决状态字的所有位都变为了0;并且也收到了刚才阻塞的SIGINT信号;
#include <iostream>
#include <signal.h>
#include <cstdlib>
#include <unistd.h>
using namespace std;


void handler(int num)
{
    if(num == SIGINT){
        cout << "刚才收到了信号SIGQUIT, 取消了阻塞,收到中断信号.." << endl;
    }
    else if (num == SIGQUIT){
        //将SIGINT信号设置为非阻塞的
        sigset_t un_bset;
        sigemptyset(&un_bset);
        sigaddset(&un_bset, SIGINT);
        sigprocmask(SIG_UNBLOCK, &un_bset, NULL);
    }
}

void print_pending(sigset_t * pset)
{
    int i = 0;
    cout << "未决状态字(64位):";
    for (i = 1; i <= 64; ++i){
        if(sigismember(pset, i))
            cout << 1;
        else
            cout << 0;
        if(i % 8 == 0){
            cout << " ";
        }
    }
    cout << endl;
}
int main()
{
    sigset_t bset;
    sigset_t pset;
    
    //设置SIGINT信号
    sigemptyset(&bset);
    sigaddset(&bset, SIGINT);

    signal(SIGINT, handler);
    signal(SIGQUIT, handler);
    //将SIGINT信号设置为阻塞的
    sigprocmask(SIG_BLOCK, &bset, NULL);

    while(1){
        //得到未决状态字
        sigpending(&pset);
        //显示未决状态字
        print_pending(&pset);

        sleep(1);
    }


    exit(0);
}
 

免责声明:文章转载自《linux信号--阻塞与未决》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇C#中字符串的常用方法arcengine 开发经典帖 【强烈推荐仔细研读】下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

linux查看进程和终止进程

1. 在LINUX命令平台输入1-2个字符后按Tab键会自动补全后面的部分(前提是要有这个东西,例如在装了tomcat的前提下,输入tomcat的to按tab)。   2. ps 命令用于查看当前正在运行的进程。   grep 是搜索   例如: ps -ef | grep java   表示查看所有进程里CMD是java的进程信息   ps -aux |...

Linux查看进程和终止进程的技巧

1. 在LINUX命令平台输入1-2个字符后按Tab键会自动补全后面的部分(前提是要有这个东西,例如在装了tomcat的前提下,输入tomcat的to按tab)。   2. ps 命令用于查看当前正在运行的进程。   grep 是搜索   例如: ps -ef | grep java   表示查看所有进程里CMD是java的进程信息   ps -aux |...

Linux中断信号的查看

中断号的查看可以使用下面的命令:“cat /proc/interrupts”。 中断号的查看也可以使用下面的命令:“cat /proc/stat” 记录了几个关于系统活动的低级统计量, 包括(但是不限于)自系统启动以来收到的中断数. stat 的每一行以一个文本字串开始, 是该行的关键词; intr 标志是我们在找的irq函数定义:/kernel/irq/...

蜕变成蝶~Linux设备驱动之异步通知和异步I/O

在设备驱动中使用异步通知可以使得对设备的访问可进行时,由驱动主动通知应用程序进行访问。因此,使用无阻塞I/O的应用程序无需轮询设备是否可访问,而阻塞访问也可以被类似“中断”的异步通知所取代。异步通知类似于硬件上的“中断”概念,比较准确的称谓是“信号驱动的异步I/O"。 1、异步通知的概念和作用 影响:阻塞--应用程序无需轮询设备是否可以访问 非阻塞--中...

Linux 多线程应用中如何编写安全的信号处理函数

http://blog.163.com/he_junwei/blog/static/1979376462014021105242552/ http://www.ibm.com/developerworks/cn/linux/l-cn-signalsec/ Linux 多线程应用中编写安全的信号处理函数 在开发多线程应用时,开发人员一般都会考虑线程安全,会...

linux进程状态详解(转)

  Linux是一个多用户,多任务的系统,可以同时运行多个用户的多个程序,就必然会产生很多的进程,而每个进程会有不同的状态。  在下文将对进程的 R、S、D、T、Z、X 六种状态做个说明。 PROCESS STATE CODES        Here are the different values that the s, stat and state...