Linux中的进程信号

news2024/10/5 17:28:21

目录

进程信号

kill/raise/abort

 硬件异常产生信号

由软件条件产生信号

 信号在内核中的表示示意图

pending:

block:

信号集操作函数

sigprocmask


进程信号

信号量和信号不同

信号量的本质是计数器,计数器可以被多进程同时看到。可以对资源进行预定。

所有进程在访问公共资源之前,必须先申请(sem)信号量

必须申请信号量的前提是所有进程必须的看到同一个信号量

信号量本身也是公共资源,所以信号量必须保证自身操作的安全性,++,--都必须是原子操作。

共享内存,消息队列,信号量中均有:

struct ipc_perm {
               key_t          __key;    /* Key supplied to shmget(2) */
               uid_t          uid;      /* Effective UID of owner */
               gid_t          gid;      /* Effective GID of owner */
               uid_t          cuid;     /* Effective UID of creator */
               gid_t          cgid;     /* Effective GID of creator */
               unsigned short mode;     /* Permissions + SHM_DEST and
                                           SHM_LOCKED flags */
               unsigned short __seq;    /* Sequence number */
           };

结构体的第一个成员的地址,在数字上,和结构体对象本身的地址数字是相等的,虽然类型不同。

进程收到信号时信号不一定会被立即处理,所以进程应有对信号的保存能力(保存在task_struct->收到信号时将对应的位图结构有0->1)。

发送信号的本质就是修改PCB中的信号位图。

#include <signal.h>
int kill(pid_t pid, int signo);
int raise(int signo);
这两个函数都是成功返回0,错误返回-1。

kill/raise/abort

kill():可以向任意进程发送任意信号

kill xxx x

raise():给自己发送任意信号

raise(x);

abort():给自己发送指定信号SIGABRT

abort();
man 7 signal

Signal      Standard   Action   Comment
  ────────────────────────────────────────────────────────────
       SIGABRT      P1990      Core    Abort signal from abort(3)
       SIGALRM      P1990      Term    Timer signal from alarm(2)
       SIGBUS       P2001      Core    Bus error (bad memory access)
       SIGCHLD      P1990      Ign     Child stopped or terminated
       SIGCLD         -        Ign     A synonym for SIGCHLD
       SIGCONT      P1990      Cont    Continue if stopped
       SIGEMT         -        Term    Emulator trap
       SIGFPE       P1990      Core    Floating-point exception

 硬件异常产生信号

硬件CPU中有mmu内存管理单元,当有越界访问时mmu会异常。OS会识别并向目标进程发送11号信号(野指针)。

由软件条件产生信号

SIGPIPE是一种由软件条件产生的信号

#include <unistd.h>
unsigned int alarm(unsigned int seconds);
调用alarm函数可以设定一个闹钟,也就是告诉内核在seconds秒之后给当前进程发SIGALRM信号, 该信号的默认处理动
作是终止当前进程。

core为核心转储,当进程出现异常时,将进程在对应时刻,在内存中的有效数据转储到磁盘中----核心转储->可以支持调试。

core-file core.xxx

实际执行信号的处理动作称为信号递达(Delivery)

信号从产生到递达之间的状态,称为信号未决(Pending)。

进程可以选择阻塞 (Block )某个信号。

被阻塞的信号产生时将保持在未决状态,直到进程解除对此信号的阻塞,才执行递达的动作.

注意,阻塞和忽略是不同的,只要信号被阻塞就不会递达,而忽略是在递达之后可选的一种处理动作。

 信号在内核中的表示示意图

置于pending表中的信号其状态为未决状态。

pending:

pending位图中,比特位的位置为信号编号,比特位的内容表示是否收到了对应的信号

block:

block位图中,比特位的位置为信号编号,比特位的内容为是否阻塞了对应的信号。

如果一个信号没有被产生,并不妨碍其可以先被阻塞。

task_struct中有字段handler_t handler[32] ,handler数组是有下标的

a.数组的位置(下标),信号的编号。

b.数组下标对应的内容,表示对应信号的处理方法。

sigset_t来存储,sigset_t称为信号集,这个类型可以表示每个信号 的“有效”或“无效”状态,在阻塞信号集中“有效”和“无效”的含义是该信号是否被阻塞,而在未决信号集中“有 效”和“无效”的含义是该信号是否处于未决状态。

信号集操作函数

#include <signal.h>
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);

sigprocmask

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

#define BLOCK_SIGNAL 2
#define MAX_SIGNUM 31

static void show_pending(const sigset_t& pending)
{
    for(int signo=MAX_SIGNUM;signo>=1;--signo)
    {
        if(sigismember(&pending,signo))
            cout<<"1";
        else cout<<"0";
    }
    cout<<"\n";
}

int main()
{
    sigset_t block,oblock,pending;
    sigemptyset(&block);
    sigemptyset(&oblock);
    //sigemptyset(&pending);
    sigaddset(&block,BLOCK_SIGNAL);

    sigprocmask(SIG_SETMASK,&block,&oblock);
    while (true)
    {
        sigemptyset(&pending);
        sigpending(&pending);
        show_pending(pending);
        sleep(1);
    }
    
}

0000000000000000000000000000000
0000000000000000000000000000000
^C

0000000000000000000000000000010

一旦对特点信号进行解除屏蔽,一般OS至少立马递达一个信号。

当某一个信号正在被递达期间,同类型信号无法递达!

当当前信号正在被捕捉时,系统会自动将当前信号加入信号屏蔽字。

当信号完成捕捉动作,系统又会自动解除对该信号的屏蔽。

void handler(int signo)
{
    printf("pid: %d, %d 号信号,正在被捕捉!\n",getpid(),signo);
}
void Count(int cnt)
{
    while (cnt)
    {
        printf("cnt: %2d\n",cnt);
        fflush(stdout);
        cnt--;
        sleep(1);
    }
    printf("\n");
}
signal(SIGCHLD,handler);
    printf("父进程, %d, ppid: %d\n",getpid(),getppid());
    pid_t id=fork();
    if(id==0)
    {
        printf("子进程, %d,ppid: %d, exit\n",getpid(),getppid());
        Count(5);
        exit(0);
    }
    while (1)
    {
        sleep(1);
    }

子进程退出时会向父进程发送17号信号。

pid_t ret=waitpid(-1,null,WNOHANG);

非阻塞式的等待子进程退出。

signal(SIGCHLD,SIG_IGN);

子进程自动退出,不会在想父进程发送信号。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2190242.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

OpenJudge | 置换选择排序

总时间限制: 1000ms 内存限制: 65536kB 描述 给定初始整数顺串&#xff0c;以及大小固定并且初始元素已知的二叉最小堆&#xff08;为完全二叉树或类似完全二叉树&#xff0c;且父元素键值总小于等于任何一个子结点的键值&#xff09;&#xff0c;要求利用堆实现置换选择排序&a…

程序员如何在 AI 时代保持核心竞争力

前言 随着 AIGC 大语言模型的不断涌现&#xff0c;AI 辅助编程工具的普及正在深刻改变程序员的工作方式。在这一趋势下&#xff0c;程序员面临着新的挑战与机遇&#xff0c;需要思考如何应对以保持并提升自身的核心竞争力。 目录 一、AI 对编程工作的影响 &#xff08;一&…

一、走进新语言

走进新语言 介绍环境配置JDK配置Kotlin配置 开发工具代码基本结构程序注释 介绍 Kotlin是一种现代但已经成熟的编程语言&#xff0c;旨在让开发人员更快乐。它简洁、安全、可与Java和其他语言互操作&#xff0c;并提供了许多在多个平台之间重用代码的方法。它由JetBrains公司于…

2.JUC

掌握 Java 并发编程&#xff0c;熟悉线程池、并发容器以及锁的机制&#xff0c;如 sychronized、ReentrantLock、AQS等。 2.0 并发基础 线程等待唤醒机制LockSupport (3种) 方式一&#xff1a;使用Object中的wait()方法让线程等待&#xff0c;使用Object中的notify()方法唤醒…

数据结构 ——— 单链表oj题:链表分割(带哨兵位单向不循环链表实现)

目录 题目要求 手搓简易单链表 代码实现 题目要求 现有一链表的头指针 ListNode* head &#xff0c;给一定值 x &#xff0c;编写一段代码将所有小于 x 的节点排在其余节点之前&#xff0c;且不能改变原来的数据顺序&#xff0c;返回重新排列后的链表的头节点 举例说明&a…

【包教包会】2D图片实现3D透视效果(支持3.x、支持原生、可合批)

将去年写的SpriteFlipper从2.x升级到3.x。 如果需要2.x版本或需要了解算法思路&#xff0c;请移步&#xff1a;https://blog.csdn.net/weixin_42714632/article/details/136745051 优化功能&#xff1a;可同时绕X轴和Y轴旋转&#xff0c;两者效果会叠加。 完美适配Web、原生…

typescript使用webpack打包编译问题

解决方案&#xff1a;在webpack.config.js中的mdule.exports中设置mode。 再次运行npm run start即可。

Python基本库的使用--urllib

开篇 本篇文章旨在总结urlib基本库的一些常用用法。 相关方法 urlopen 用户打开和读取URL。 import urllib.requestresponse urllib.request.urlopen(https://www.python.org) print(response.read().decode(utf-8))带data参数 import urllib.parse import urllib.requestda…

【计算复杂性理论】P可归约(归约,P-reducible)与P、NP、NP-Hard、NP-Complete问题

1 问题背景 如果想要了解P问题、NP问题、NP-Hard问题、NP-Complete问题之间的关系&#xff0c;那就需要从了解NP-complete问题和归约概念开始。上一篇文章中&#xff0c;我们介绍了计算复杂性理论的奠基之作《The Complexity of Theorem-Proving Procedures》&#xff0c;在这篇…

初识算法 · 滑动窗口(1)

目录 前言&#xff1a; 长度最小的子数组 题目解析 算法原理 算法编写 无重复长度的最小字符串 题目解析 算法原理 算法编写 前言&#xff1a; 本文开始&#xff0c;介绍的是滑动窗口算法类型的题目&#xff0c;滑动窗口本质上其实也是双指针&#xff0c;但是呢&#…

初识数据结构--时间复杂度 和 空间复杂度

数据结构前言 数据结构 数据结构是计算机存储、组织数据的方式(指不仅能存储数据&#xff0c;还能够管理数据-->增删改)。指相互之间存在一种或多种特定关系的数据元素的集合。没有单一的数据结构对所有用途都有用&#xff0c;所以我们要学习各种的数据结构&#xff0c;比…

[Python] 编程入门:理解变量类型

文章目录 [toc] 整数常见操作 浮点数字符串字符串中混用引号问题字符串长度计算字符串拼接 布尔类型动态类型特性类型转换结语 收录专栏&#xff1a;[Python] 在编程中&#xff0c;变量是用于存储数据的容器&#xff0c;而不同的变量类型则用来存储不同种类的数据。Python 与 C…

Springboot项目整合RabbitMQ+Redis实现可靠的阿里云短信异步收发功能(手把手实操详细教程)

文章目录 1、项目介绍1.1、项目描述1.2、项目结构 2、创建项目(idea)2.1、依赖引入2.2、 配置文件2.3、 数据库表2.4、 实体类2.5、 配置类2.6、 验证码服务类2.7、 短信发送服务类2.8、 消费者类2.9、发送服务类2.10、定时任务类2.11、启动类2.12、测试控制器 3、效果测试4、总…

计算机科学英语词汇汇总(上)(Computer Science English Complete Vocabulary)

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 本人主要分享计算机核心技…

对不经常变动的数据集合添加Redis缓存

目录 前言 什么是缓存 如何使用缓存 添加商户缓存 缓存模型和思路 实现代码 问题分析 解决方案 实现商铺和缓存与数据库双写一致 实现代码 前言 什么是缓存 缓存(Cache),就是数据交换的缓冲区,俗称的缓存就是缓冲区内的数据,一般从数据库中获取,存储于本地代码 缓存…

【框架篇】过滤器和拦截器的区别以及使用场景

在项目开发中&#xff0c;常常会同时配置拦截器&#xff08;Interceptor&#xff09;和过滤器&#xff08;Filter&#xff09;&#xff0c;以下就是它们两个主要的区别&#xff1a; 过滤器&#xff08;Filter&#xff09; 配置和实现 Filter的实现还是很简单的&#xff0c;可…

提升快递管理效率的必备技能:教你批量查询与导出物流信息

在当今快节奏的商业环境中&#xff0c;快递与物流行业的效率直接关系到企业的运营成本和客户满意度。随着订单量的不断增加&#xff0c;如何高效地管理和追踪大量的物流信息成为了企业面临的一大挑战。批量查询与导出物流信息作为一种高效的数据处理手段&#xff0c;正逐渐成为…

微信小程序-npm支持-如何使用npm包

文章目录 1、在内建终端中打开2、npm init -y3、Vant Weapp4、通过 npm 安装5、构建 npm 1、在内建终端中打开 Windows PowerShell 版权所有 (C) Microsoft Corporation。保留所有权利。尝试新的跨平台 PowerShell https://aka.ms/pscore6PS C:\Users\dgq\WeChatProjects\minip…

重学SpringBoot3-集成Redis(三)

更多SpringBoot3内容请关注我的专栏&#xff1a;《SpringBoot3》 期待您的点赞&#x1f44d;收藏⭐评论✍ 重学SpringBoot3-集成Redis&#xff08;三&#xff09; 1. 引入 Redis 依赖2. 配置 RedisCacheManager 及自定义过期策略2.1 示例代码&#xff1a;自定义过期策略 3. 配置…

大学生就业招聘系统:Spring Boot技术解析

3系统分析 3.1可行性分析 通过对本大学生就业招聘系统实行的目的初步调查和分析&#xff0c;提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、经济可行性、操作可行性等方面进行分析。 3.1.1技术可行性 本大学生就业招聘系统采用JAVA作为开发语言&#xff0c;S…