信号——block+pending+handler表

信号

信号——block+pending+handler表_第1张图片
注意 :这由三张表,block只能添加修改pending只能获取 , handler只能修改

基础知识

  • 抵达——> 执行 / 忽略
  • sigset_t 信号集
  • 被阻塞的信号产生时将保持在未决状态,直到进程解除对此信号的阻塞,才执行递达的动作

信号集操作

#include
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);

使用这个函数改变某个特定的信号对应的处理方法—— handler 表中的方法

#include
void abort(void);

发送特定的信号6) SIGABRT——终止进程


#include
int raise(int sig);

向当前进程发送指定信号


#include
int sigemptyset(sigset_t *set);
int sigfillset(sigset_t *set);
int sigaddset (sigset_t *set, int signo);
int sigdelset(sigset_t *set, int signo);
int sigismember(const sigset_t *set, int signo);

注意:对sigset_t 生成的变量操作,只是将信号存储在栈上,并没有加进今进程pdb中


#include
int sigprocmask(int how, const sigset_t *set, sigset_t *oset);

注意 : 使用这个函数将加入pcb中 ,使用这个函数只能对block表进行修改

how
SIG_BLOCK——添加
SIG_UNBLOCK——删除
SIG_SETMASK——设置
set 设置进pcb中,将pcb中原有的状态寄存如 oset


#include
int sigpending(sigset_t *set);

想要信号存入pending表中,可以先将这个信号阻塞,因为对于阻塞的信号,暂存在pending表中,直到阻塞解除
获取进程中所有 pending 信号

#include 
#include 
#include 
#include 
#include
#include
#include


using namespace std;

int main()
{
    printf("%d\n",getpid());
    sigset_t sig;

    sigemptyset(&sig);
    sigaddset(&sig,2);
    sigprocmask(SIG_SETMASK,&sig,nullptr);
        while(1)
    {
        // 将正在处理的信号先将这个位置变成0,如果在处理这个信号的时候来相同信号,就会默认加入pending,默认将这个信号屏蔽
        sigset_t pending;
        sigpending(&pending);
        for(int i=31;i>0;i--)
        {
            if(sigismember(&pending,i)) printf("1");
            else printf("0");
        }
        puts("");

        // 获取block列表,观察是否进行屏蔽——无法获取block列表
        sleep(1);
    }
    // signal(2,handler);

    while(1) ;

    return 0;
}

信号——block+pending+handler表_第2张图片


#include
int sigaction(int signo, const struct sigaction *act, struct sigaction *oact);

修改handler表对应的方法
函数机制介绍

在处理a信号的过程中,自动将a信号加入block表,直到结束自动恢复

使用举例

#include 
#include 
#include 
#include 
#include
#include
#include


using namespace std;

void handler(int signum)
{
    printf("signal: %d\n",signum);
    while(1)
    {
        // 将正在处理的信号先将这个位置变成0,如果在处理这个信号的时候来相同信号,就会默认加入pending,默认将这个信号屏蔽
        sigset_t pending;
        sigpending(&pending);
        for(int i=31;i>0;i--)
        {
            if(sigismember(&pending,i)) printf("1");
            else printf("0");
        }
        puts("");

        // 获取block列表,观察是否进行屏蔽——无法获取block列表
        sleep(1);
    }
}

int main()
{
    struct sigaction act;
    act.sa_handler=handler;
    sigemptyset(&act.sa_mask);
    sigaddset(&act.sa_mask,3);// 将3号信号加入信号集中
    
    sigaction(2,&act,nullptr);
    cout<< getpid()<<endl;
    while(1) ;

    return 0;
}

信号——block+pending+handler表_第3张图片
信号——block+pending+handler表_第4张图片

sigaddset(&act.sa_mask,3); // 将3号信号加入信号集中
sigaction(2,&act,nullptr);

说明一下这个代码,意思是将3号信号加入信号集,然后将2号信号方法更新进handler表中,特别注意的是,在检测到2号信号的时候,才会将2,3信号加入block表;只发3号信号,还是像普通信号一样

你可能感兴趣的:(Linux,信号)