15 - 信号处理设计模式

news2024/12/24 2:06:28

---- 整理自狄泰软件唐佐林老师课程

查看所有文章链接:(更新中)Linux系统编程训练营 - 目录

文章目录

  • 1. Linux应用程序安全性讨论
    • 1.1 问题
    • 1.2 不同场景
      • 1.2.1 场景一:不需要处理信号
      • 1.2.2 场景二:需要处理信号
  • 2. 场景一:不需要信号处理(单一功能应用程序)
  • 3. 场景二:需要处理信号(长时间运行的应用)
    • 3.1 同步解决方案(单任务)
      • 3.1.1 方案设计一
        • 3.1.1.1 同步方案示例一
        • 3.1.1.2 编程实验
        • 3.1.1.3 存在的问题
      • 3.1.2 方案设计二
        • 3.1.2.1 关键系统函数
        • 3.1.2.2 编程实验
        • 3.1.2.3 存在的问题
        • 3.1.2.4 思考
    • 3.2 异步解决方案(多任务)
      • 3.2.1 问题
      • 3.2.2 多线程信号处理
      • 3.2.3 方案
      • 3.2.4 进程与线程
        • 3.2.4.1 Linux多线程API函数
        • 3.2.4.2 多线程编程示例
      • 3.2.5 异步方案示例
      • 3.2.6 编程实验:多线程信号处理
  • 4. 信号设计模式小结

1. Linux应用程序安全性讨论

1.1 问题

  • 如何编写信号安全的应用程序?

1.2 不同场景

1.2.1 场景一:不需要处理信号

应用程序实现单一功能,不需要关注信号
如:数据处理程序,文件加密程序,科学计算程序

1.2.2 场景二:需要处理信号

应用程序长时间运行,需要关注信号,并及时处理
如:服务端程序,上位机程序

2. 场景一:不需要信号处理(单一功能应用程序)

在代码层面,直接阻塞所有可能的信号(本质上就是信号始终处于未决状态,无法递达进程)

在这里插入图片描述

  • 编程实验:不需要处理信号

【参看链接】:15 - 信号处理设计模式 / 00不需要处理信号场景/main.c

在这里插入图片描述
在这里插入图片描述

3. 场景二:需要处理信号(长时间运行的应用)

  • 同步方案
    • 通过 标记 同步处理信号,整个应用中 只有一个执行流
  • 异步方案
    • 专用任务处理,应用中存在 多个执行流(多线程应用)
    • 设置 专用于信号处理的任务,其它任务忽略信号,专注功能实现

3.1 同步解决方案(单任务)

  • 信号处理逻辑与程序逻辑位于同一个上下文
    即:信号处理函数与主函数不存在资源竞争关系

3.1.1 方案设计一

  1. 将任务分解为 子任务(每个任务可对应一个函数)
  2. 信号递达时,信号处理函数中 标记 递达状态
  3. 子任务处理结束后,真正执行信号处理

在这里插入图片描述

3.1.1.1 同步方案示例一

在这里插入图片描述

3.1.1.2 编程实验

【参看链接】:15 - 信号处理设计模式 / 01处理信号场景_同步方案

  1. 对于不可靠信号

在这里插入图片描述
在这里插入图片描述

  1. 对于可靠信号存在问题

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.1.1.3 存在的问题

  • 由于给每个信号唯一的标记位置,因此,所有信号转变为不可靠信号,并且仅保留最近递达的信号信息。
  • 可能改进方案:
    • 标记位置设计为链表,信号递达后在对应位置的链表处增加结点保留信号信息
      (增加结点涉及到malloc,不安全)

3.1.2 方案设计二

  1. 将任务分解为子任务(每个任务可对应一个函数)
  2. 创建 信号文件描述符,并阻塞所有信号(可靠信号递达前位于内核队列)
    • 意义:化被动为主动,原先任务的执行流在收到信号后被动中断。现在主动去检查是否有信号,如果有信号,将信号取出来处理,此时就需要文件描述符。
  3. 子任务处理结束后,通过 select机制 判断是否有信号需要处理
    • true:处理信号,false:等待超时

3.1.2.1 关键系统函数

在这里插入图片描述

  • 使用signalfd()处理信号
    先屏蔽所有信号(无法递达进程),之后为屏蔽信号创建文件描述符,当时机成熟,通过read()系统调用读取未决信号(主动接收信号)。

在这里插入图片描述

  • 使用select()监听文件描述符

在这里插入图片描述

  • 使用select()处理信号

在这里插入图片描述

3.1.2.2 编程实验

【参看链接】:15 - 信号处理设计模式 / 02处理信号场景_同步方案_select

  1. 可靠信号

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  1. 不可靠信号

在这里插入图片描述
在这里插入图片描述

3.1.2.3 存在的问题

  • 虽然解决了信号丢失的问题,但是实时性不好。由于使用了select()机制,即便没有信号需要处理,也需要等待select超时,任务 实时性 受到影响

在这里插入图片描述

3.1.2.4 思考

  • 是否可以兼顾 信号处理任务执行 的实时性?

3.2 异步解决方案(多任务)

  • 使用独立任务处理信号,程序逻辑在其它任务中执行
    即:通过 多线程 分离信号处理与程序逻辑
    • 主线程:专用于处理信号
    • 其它线程:完成程序功能

3.2.1 问题

  • 信号递达进程后,在 哪一个执行流 中进行处理?

3.2.2 多线程信号处理

  • 信号的发送目标是 进程,而不是某个特定的线程
  • 发送给进程的信号仅递送给一个线程 ==> 哪一个线程处理?
  • 内核在不会阻塞目标信号的线程中进行随机选择
  • 每个线程拥有独立的信号屏蔽掩码

3.2.3 方案

  • 主线程:对目标信号设置信号处理的方式
    • 当信号递达进程时,只可能是 主线程 进行信号处理
  • 其它线程:首先屏蔽所有可能的信号(简单粗暴),之后执行任务代码
    • 无法接收到信号,不具备信号处理能力

3.2.4 进程与线程

  • 进程:应用程序的一次加载执行(系统进行资源分配的基本单位)
  • 线程:进程中的程序执行流
    • 一个进程可以存在多个线程(至少存在一个线程)
    • 每个线程执行不同的任务(多个线程可并行执行)
    • 同一个进程中的多个线程共享进程的系统资源

3.2.4.1 Linux多线程API函数

在这里插入图片描述

  • 线程标识:pthread_t pthread_self(void);
    • 获取当前线程的ID标识(tid)
  • 线程等待:int pthread_join(pthread_t thread, void** retval);
    • 等待目标线程执行结束

3.2.4.2 多线程编程示例

在这里插入图片描述

3.2.5 异步方案示例

  1. 主线程

在这里插入图片描述

  1. 任务线程

在这里插入图片描述

3.2.6 编程实验:多线程信号处理

【参看链接】:15 - 信号处理设计模式 / 03处理信号场景_异步方案_多线程

  1. 不可靠信号

在这里插入图片描述
在这里插入图片描述

  1. 可靠信号

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4. 信号设计模式小结

  • 多数程序不需要处理信号,因此可直接屏蔽信号
  • 需要处理信号的程序,重点考虑信号安全性问题
    • 同步 处理方案,通过设计让 任务代码信号处理代码 交替执行
      问题:信号处理是否及时?任务执行是否实时?
    • 异步 处理方案,任务代码信号处理代码 位于 不同执行流
      问题:将信号安全性问题转换为线程安全性问题,因此,程序本身是否做到线程安全?

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

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

相关文章

SQLmap使用指南(包含使用SQLmap获取shell)

文章标题 一:SQLmap基础知识二:SQLmap各大模块中的常用命令(一) 基础命令(二) target模块(三) Emuneration模块(四)其他命令 三:SQLmap应用示例&a…

数据结构_进阶(2):二叉树的OJ练习题

目录 1. 二叉树创建字符串。OJ链接 2. 二叉树的分层遍历1。OJ链接 3. 二叉树的分层遍历2。OJ链接 4. 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先 。OJ链接 5. 二叉树搜索树转换成排序双向链表。OJ链接 6. 根据一棵树的前序遍历与中序遍历构造二叉树。 OJ链接…

2023年NOC决赛-加码未来编程赛项决赛模拟题-Python模拟题--卷4

第一题、计算 1+2+3+⋯+(n−1)+n 的值,其中正整数 n 不大于 100。由于你没有高斯聪明,所以你不被允许使用等差数列求和公式直接求出答案。 输入格式 输入一个正整数 n。 输出格式 输出一个正整数,表示最后求和的答案。 输入输出样例 输入 #1 100 输出 #1 5050 第二…

手撕自定义类型:结构体,枚举,联合——【C语言】

在开始学习之前我们先来欣赏一下五岳之一华山的风景,来营造一个好心情,只有一个好心情我们才能更好的学习 目录 结构体 1 结构体的声明 1.1 结构的基础知识 1.2 结构的声明 1.3 特殊的声明 1.4 结构的自引用 1.5 结构体变量的定义和初始化 1.6 …

Go语言之重要数组类型切片(slice)make,append函数

切片是一个动态数组,因为数组的长度是固定的,所以操作起来很不方便,比如一个names数组,我想增加一个学生姓名都没有办法,十分不灵活。所以在开发中数组并不常用,切片类型才是大量使用的。 切片基本操作 切片…

Linux系统文件编程及文件读、写操作

Linux 系统编程Day01 文章目录 Linux 系统编程Day011.文件编程概述1.1 文件的打开及创建1.1.1 参数说明1.1.2 文件写入操作示例1.1.3 文件的权限 2.文件操作2.1 写入文件2.2 文件读取操作2.3 文件的光标移动操作 3.文件操作原理简述3.1文件描述符3.2 Linux文件操作流程 1.文件编…

【数据结构】二叉树的前中后序遍历(C语言)

文章目录 什么是二叉树树相关的概念树的表示形式特殊的二叉树如何创造出一棵二叉树二叉树的遍历先序遍历(前序遍历)中序遍历后序遍历 总结 什么是二叉树 [二叉树] 顾名思义就是有两个分支节点的树,不仅如此,除了叶子外的所有节点都具有两个分支节点&…

单个电源模块给多个负载使用,并且电源后还经过了磁珠-二级电源直流压降仿真

单个电源模块给多个负载使用,并且电源后还经过了磁珠-二级电源直流压降仿真 下面介绍单个电源模块给多个负载使用,并且电源后还经过了磁珠-二级电源直流压降仿真,常见于二级压降仿真,以下图为例

备战秋招 | 笔试强训5

目录 一、选择题 二、编程题 三、选择题题解 四、编程题题解 一、选择题 1、在上下文和头文件均正常情况下,以下程序的输出结果是() int x 1; do {printf("%2d\n",x); }while(x--); A. 1 B. 无任何输出 C. 2 D. 陷入死循环 …

三种智能算法优化PID参数软件,MATLABAPP开发

今天的主题是:三种智能算法优化常见传递函数的PID参数,采用MATLAB APP Designer 开发。提供代码源程序,可以自行修改源代码(不是封装软件) 这个软件基本涵盖了所有的传递函数类型,传递函数的参数简单易改。…

【Java反射机制详解】—— 每天一点小知识

💧 J a v a 反射机制详解 \color{#FF1493}{Java反射机制详解} Java反射机制详解💧 🌷 仰望天空,妳我亦是行人.✨ 🦄 个人主页——微风撞见云的博客🎐 🐳 《数据结构与算法》专栏的文章…

pytest 参数化进阶

目录 前言: 语法 参数化误区 实践 简要回顾 前言: pytest是一个功能强大的Python测试框架,它提供了参数化功能,可以帮助简化测试用例的编写和管理。 语法 本文就赶紧聊一聊 pytest 的参数化是怎么玩的。 pytest.mark.par…

week27

这周是磨难的一周不知道NT装了多少次系统,删除了多少数据好消息是把BIOS和ubuntu安装地很熟练了,而且经过爱上了心仪的Ubuntu23.04,就是她了坏消息是一个学期做的笔记全都没了,以后不好回忆了,好消息是不用考试了&…

总结929

今日做了一篇阅读题,差点全军覆没,通过这篇阅读,主要说明了两大问题,一个是单词,背的还不够牢固,其二,语法功底还不够扎实。但说实话,在语法方面,还是下了一番功夫&#…

linux 内网批量快速传输大文件 nc

使用nc工具 传输内网宽带拉满先运行接收端 开始监听使用 ansible 拷贝脚本到其它接收端服务器批量运行接收端脚本查看nc是否运行运行发送端运行发送端脚本开始传输文件 传输内网宽带拉满 先运行接收端 开始监听 接收端脚本 re.sh #!/bin/bash #Revision: 1.0 #Author:…

动态规划(一) —— 从背包系列问题看DP

前言 动态规划可以算是算法初学者的噩梦哈哈,这段时间荔枝在持续学习Java后端的同时也没有忘记刷题嘿嘿嘿,总算把代码随想录上给出的有关动态规划的题目刷完了。接下来的几篇文章荔枝将会对于刷过的动态规划问题做出总结并给出相应的个人体会和理解。在本…

compose之沉浸式(侵入式)状态栏(隐藏状态栏)

沉浸式(侵入式)状态栏 效果图: 1、代码加入:WindowCompat.setDecorFitsSystemWindows(window, false) ComposeTestTheme {WindowCompat.setDecorFitsSystemWindows(window, false)Greeting("Android")} 2、沉浸式(侵入式)主题: …

消息推送(websocket)集群化解决方案

目录 需求分析解决方案实现步骤架构图配置websocket请求地址配置websocket连接前置和连接关闭监听配置websocket处理程序配置redis交换机配置redis订阅监听配置redis发布监听需求分析 及时信息传递:消息推送功能能够确保网站向用户发送及时的重要信息,包括新闻更新、促销活动…

消息队列——rabbitmq的不同工作模式

目录 Work queues 工作队列模式 Pub/Sub 订阅模式 Routing路由模式 Topics通配符模式 工作模式总结 Work queues 工作队列模式 C1和C2属于竞争关系,一个消息只有一个消费者可以取到。 代码部分只需要用两个消费者进程监听同一个队里即可。 两个消费者呈现竞争关…

Redis进阶底层原理-主从复制

Redis的主从节点都会记录对方的信息,核心还包括ReplicationID 和 offset , ReplicationID : 主从节点实例的ID ,redis内部就是通过这个id去识别主从节点。offset:数据同步偏移量,也就是从节点每次从主节点同…