【Linux】进程信号的保存(二)

文章目录

信号保存

信号产生后,操作系统将信号发给进程,进程就要保存信号。
为什么信号要保存?

因为进程收到信号后,可能在忙其他事情,不会立即处理信号,就产生了时间窗口

相关概念

  • 实际处理信号的过程叫信号递达(Delivery)
  • 信号产生到处理的过程叫做信号未决(Pending)
  • 进程可以==阻塞(Block)==某个信号,
  • 被阻塞的信号将保持在未决状态
  • 被阻塞和忽略是不一样的,被阻塞是递达不了,忽略是信号递达后的一种处理方式

🚩内核三张表


进程PCB里面指向三张表,一张阻塞表block,一张未决表pending,一张处理方式handler表

阻塞状态信号不会被处理,直到解除阻塞状态

也就是说2号信号会一直保持此状态,直到block解除,pending就会被处理

3号信号block为1,阻塞,现在的状态是从未收到过信号,如果收到信号pending会置1==

每个信号都有自己的默认处理方式

如上上图,1号信号默认处理
2号信号,忽略处理

signal(SIGINT,SIG_DFL); 恢复2号

signal(SIGQUIT,SIG_IGN); 将3号忽略


handler表中存的函数指针,每个函数指针指向一个信号处理方式

c 复制代码
void printpending(sigset_t &pending)
{
    for(int i=31;i>=1;i--)
    {
        if(sigismember(&pending,i))
        {
            cout<<1;
        }
        else{
            cout<<0;
        }
    }
    cout<<endl;
}
int main()
{
    sigset_t bset , oset;//在栈上开辟空间,属于用户区
    sigemptyset(&bset);
    sigemptyset(&oset);
    sigaddset(&bset,2);//没进入内核,只是把bset这个数设置了
    //调用系统调用
    sigprocmask(SIG_SETMASK, &bset, &oset); //把2屏蔽了

    sigset_t pending;
    while(1)
    {
        int n=sigpending(&pending);
        if(n<0)
        continue;
        printpending(pending);
        sleep(1);
    }
    
    return 0;
}

sigprocmask(SIG_SETMASK,&bset,&oset);

将阻塞表设为bset,其中上次阻塞表保存在oset,不想保存放nullptr就行


我们可以看到阻塞之后,我们向进程发2号信号,pending挂起

解除阻塞

c 复制代码
 int cnt=0;
    while(1)
    {
        int n=sigpending(&pending);
        if(n<0)
        continue;
        printpending(pending);
        sleep(1);
        cnt++;
        if(cnt==20)
        {
            cout<<"unlock"<<endl;
            sigprocmask(SIG_SETMASK,&oset,nullptr);//解除
        }
    }

解除后立马终止了

所有信号都能被阻塞吗,肯定不是

c 复制代码
int main()
{
    sigset_t bset , oset;
    sigemptyset(&bset);
    sigemptyset(&oset);
    sigaddset(&bset,2);
    for(int i=1;i<=31;i++)
    {
        sigaddset(&bset,i);
    }

    sigprocmask(SIG_SETMASK,&bset,&oset);
    sigset_t pending;
    while(1)
    {
        int n=sigpending(&pending);
        if(n<0)
        continue;
        printpending(pending);
        sleep(1);
    }
    return 0;
}


相关推荐
额额额对了1 分钟前
Linux 进程间通信(IPC)核心机制:消息队列、共享内存与信号量详解
linux·网络·网络协议
西索斯coding11 分钟前
doubao-seed-2.1-turbo 调用一直 401 怎么办?pro 版同样的 Key 却正常——5 分钟排查定位指南
java·服务器·数据库·ai
zx_7414848134 分钟前
【Linux入门】Linux 安装:VMware Workstation Pro 安装 CentOS 7 保姆级图文教程
linux·centos
Persistent的粽子!1 小时前
C++:类与对象(二)
开发语言·c++
思麟呀1 小时前
嵌入式入门(一)宏观生态到首次烧录
c语言·嵌入式硬件
myy-learn1 小时前
31-TCP并发
服务器·网络·tcp/ip
名字还没想好☜1 小时前
Docker buildx 多架构镜像实战:一次构建 amd64+arm64,告别 exec format error
运维·docker·eureka·架构·kubernetes
Omics Pro1 小时前
Arc研究所Cell|全新虚拟细胞官方基准评测框架
大数据·人工智能·深度学习·算法·机器学习
白狐_7981 小时前
408 数据结构|红黑树插入:只记两大类
数据结构
智购科技无人售货机厂家1 小时前
2026自动售货机备用电池管理系统设计:从充放电保护到健康监测的工程实践~YH
大数据·linux·单片机·嵌入式硬件·微信