首页 > 系统相关 >linux中的标准信号

linux中的标准信号

时间:2024-09-29 19:44:40浏览次数:1  
标签:int 阻塞 发送 标准 sig 信号 linux 进程

什么是标准信号

信号是事件发生时对进程的通知机制。有时也称之为软件中断。信号与硬件中断的相似之处在于打断了程序执行的正常流程,大多数情况下,无法预测信号到达的精确时间。

信号分为两大类。第一组用于内核向进程通知事件,构成所谓传统或者标准信号。Linux 中标准信号的编号范围为 1~31。另一组信号由实时信号构成。

以下讨论均指代标准信号

我们可以把信号看做是进程间交流的工具,即进程间通信

举个例子,两个人分别处在不同的孤岛上,如果手机没有信号,那么他们就无法进行交流,反之,则可以进行交流

进程也是类似的,由于虚拟内存,进程之间是相互独立的,就相当于孤岛,他们可以通过信号来进行通信也就是进程间通信

有了大致的概念后,让我们具体看看信号长什么样子吧

针对每个信号,都定义了一个唯一的(小)整数,从 1 开始顺序展开。<signal.h>以 SIGxxxx形式的符号名对这些整数做了定义。

范围一般是1-31,比如说我们常用的 Ctrl+C,它对应的信号就是 SININT

信号的产生

1

发送信号的系统调用

进程间发送信号,还需要适当的权限,这里就不详细展开了,以下关注的是使用的系统调用

  • int kill(pid_t pid, int sig);

    • pid是要发送的对象的进程id(即 发送给谁)
      3

    • sig是发送的信号(即 发送什么)

  • int raise(int sig) 向自身传递信号,相当于kill(getpid(), sig)

  • int killpg(pid_t pgrp, int sig) 向某一个进程组的所有成员发送一个信号

检查进程的存在

kill()系统调用还有另一重功用。若将参数 sig 指定为 0(即所谓空信号),则无信号发送。相反,kill()仅会去执行错误检查,查看是否可以向目标进程发送信号。从另一角度来看,这意味着,可以使用空信号来检测具有特定进程 ID 的进程是否存在。若发送空信号失败,且 errno为 ESRCH,则表明目标进程不存在。如果调用失败,且 errno 为 EPERM(表示进程存在,但无权向目标进程发送信号)或者调用成功(有权向进程发送信号),那么就表示进程存在。

这段话讲的就是使用kill去判断进程是否存在,当sig=0时,就可以判断,这时候不会发送信号,然后我们可以根据kill的返回值以及错误码errno去判断进程的情况

信号集

信号集,就是信号的集合,有时候我们需要指定一组信号,而非单个信号

数据结构

可以使用sigset_t这个数据类型去定义一个信号集

  sigset_t signal_set;

初始化信号集

  • 清空信号集:int sigemptyset(sigset_t *set); 信号集中无可用信号
  • 填充信号集:int sigfillset(sigset_t *set); 将所有可用信号填充到信号集中

修改信号集

  • 向信号集添加单个信号:int sigaddset(sigset_t *set, int sig);
  • 向信号集移除单个信号:int sigdelset(sigset_t *set, int sig);

成员检测

  • 检测信号集中是否有特定信号:int sigismember(const sigset_t *set, int sig);

信号的接收

信号的阻塞状态

信号掩码

核会为每个进程维护一个信号掩码,即一组信号,并将阻塞其针对该进程的传递。如果将遭阻塞的信号发送给某进程,那么对该信号的传递将延后,直至从进程信号掩码中移除该信号,从而解除阻塞为止。

如何阻塞/移除阻塞信号

5

我们先定义两个信号集,一个存储要阻塞的信号,一个存储改动前的掩码(改动前的阻塞信号集)

  sigset_t blockSet, prevMask;
  • 阻塞一个信号
  // 阻塞信号SIGINT
  sigemptyset(&blockSet);
  sigaddset(&blockSet, SIGINT);
  sigprocmask(SIG_BLOCK, &blockSet, &prevMask);
  • 移除一个阻塞信号
    和上面的差不多,将SIG_BLOCK换成SIG_UNBLOCK就行了

  • 设置掩码信号集

  // 以下是恢复原先的阻塞信号集
  sigprocmask(SIG_SETMASK, &prevMask, NULL);

需要注意的是,有两个信号是无法被阻塞的

系统将忽略试图阻塞 SIGKILL 和 SIGSTOP 信号的请求。如果试图阻塞这些信号,sigprocmask()函数既不会予以关注,也不会产生错误。

信号的等待状态

如果某进程接受了一个该进程正在阻塞的信号,那么会将该信号填加到进程的等待信号集中。当(且如果)之后解除了对该信号的锁定时,会随之将信号传递给此进程。

我的理解是,信号的阻塞是进程为了避免因某些信号的传递而中断设置的一种屏蔽措施,当这些被阻塞的信号发送时,这些信号会被存储在该进程的等待信号集,不会去中断进程,只有等进程移除了信号的阻塞(改变掩码)才能传递信号

不对信号进行排队处理

等待信号集只是一个掩码,仅表明一个信号是否发生,而未表明其发生的次数。换言之,如果同一信号在阻塞状态下产生多次,那么会将该信号记录在等待信号集中,并在稍后仅传递一次

不进行排队处理其实就是同一种信号只处理一次,不会一次处理多个同种信号

获取等待信号集

11

set参数是用来接收返回的等待信号集,然后可以使用sigismember函数来判断某个信号是否处于等待状态中

信号的处理

信号处理器程序(也称为信号捕捉器)是当指定信号传递给进程时将会调用的一个数。

以下是信号处理的流程
2

当进程收到信号时,会产生一个中断,cpu会转到信号处理器程序执行,然后在返回中断点,恢复进程的执行

不同的处理(响应)方式

信号的默认行为

  • term 表示信号终止进程
  • core 表示进程产生核心转储文件并退出
  • ignore 表示忽略该信号
  • stop 表示信号停止了进程
  • cont 表示信号恢复了一个已停止的进程

自定义行为

信号处理器函数一般具有以下格式

void signal_handler(int sig) {...};
  • signal函数

7

  // 捕获SIGINT信号,并执行信号处理器函数
  signal(SIGINT, signal_handler);
  • sigaction函数,提供了比signal函数更灵活精细的控制,可移植性更高

8

以下是struct sigaction的结构
9

sigaction中的act指向的是当前的信号处理信息,oldact指向的是旧有的信号处理信息,oldact可以是指为NULL

  struct sigaction sa; 
  sa.sa_handler = signal_handler; // 设置处理函数
  sigemptyset(&sa.sa_mask); // 清空掩码
  sa.sa_flags = 0; // 可以设置标志,用 | 进行连接

  sigaction(SIGINT, &sa, NULL); // 注册SIGINT信号处理器

等待信号

这个和信号的等待状态是不同的,这个是主动的,等待信号发送,而那个是被动的,信号已经发送了,但进程没有接收

10

借助于 pause(),进程可暂停执行,直至信号到达为止

标签:int,阻塞,发送,标准,sig,信号,linux,进程
From: https://www.cnblogs.com/dylaris/p/18440485

相关文章

  • linux: ss的常用场景
    一,列出所有监听中的端口#-l:  仅显示处于监听状态的套接字#-n: 以数字格式显示地址和端口。使用此选项可以避免将地址和端口转换为主机名或服务名,从而加快查询速度#-t: 仅显示TCP套接字信息#-p: 显示与每个套接字相关联的进程信息,包括进程ID和进程名称ss-lntp二,查......
  • 服务器Linux的一些常用命令,收藏备用!
    在Linux服务器的管理和维护过程中,掌握一些常用的命令是非常必要的。这些命令不仅可以帮助你更好地了解和控制系统,还能提高工作效率,减少错误发生的概率。本文将详细介绍一些在Linux服务器上常用的命令,覆盖从基本的文件操作到高级的系统管理,力求内容全面,帮助读者深入理解每一个命令......
  • Linux小tracks
    1.修改dns服务器:/etc/resolv.conf2.ssh证书连接简易操作:ssh-keygen-trsa-b2048|生成密钥对ssh-copy-idusername@remote_host|将你的公钥(通常是~/.ssh/id_rsa.pub)添加到你想要连接的服务器上的~/.ssh/authorized_keys文件中。你可以使用ssh-copy-id命令来......
  • Web服务器小项目(Linux / C / epoll)
    欢迎访问我的另一个博客:https://xingzhu.top/注意:前置知识:HTTP:https://xingzhu.top/archives/web-fu-wu-qiLinux多线程:https://xingzhu.top/archives/duo-xian-cheng源码放github上了,欢迎star:https://github.com/xingzhuz/webServer思路实现代码server.h......
  • 轻松上手Linux,掌握这些基础指令就够了
    想要成为Linux高手吗?掌握常用指令是关键!本指南将为你介绍最实用的Linux指令,让你轻松管理你的系统,从文件操作到系统监控,我们将一步步引导你成为Linux的行家里手,快来学习这些必备技能,让你的工作效率飞速提升!目录1、whoami命令语法:whoani功能:显示当前用户名2、pwd命令......
  • linux io 模型浅析
    缩写释义:io:input/output输入输出fd:filedescriptor文件描述符,一个用于标识打开文件或网络连接的整数,系统为进程打开的每个文件保留一个文件描述符,可以用于读写文件IO模型的分类:分为同步IO和异步IO。同步IO:用户发起IO,用户阻塞或轮训的查看是否就绪,就绪后用户进行内核态到......
  • Linux应急响应技巧整理
    吉祥知识星球http://mp.weixin.qq.com/s?__biz=MzkwNjY1Mzc0Nw==&mid=2247485367&idx=1&sn=837891059c360ad60db7e9ac980a3321&chksm=c0e47eebf793f7fdb8fcd7eed8ce29160cf79ba303b59858ba3a6660c6dac536774afb2a6330&scene=21#wechat_redirect《网安面试指南》http://......
  • 线上培训中的知识库搭建:标准化与定制化的平衡
    在数字化时代,线上培训已成为企业提升员工技能、促进知识传承与创新的重要手段。而构建一个高效、实用的线上培训知识库,则是实现这一目标的关键。然而,在知识库的建设过程中,如何平衡内容的标准化与员工的定制化学习需求,成为了一个亟待解决的问题。本文将从标准化奠定基石、定......
  • 推出TMS320VC5416GWS120、TMS320VC5416PGE160、TMS320VC5416ZWS160定点数字信号处理器
    系列概述:TMS320VC5416定点数字信号处理器(DSP)基于先进的改进型哈佛架构打造,具有一条程序存储器总线和三条数据存储器总线。该处理器采用具有高并行能力的算术逻辑单元(ALU)、特定于应用的硬件逻辑、片上存储器和附加片上外设。高度专业化的指令集是TMS320VC5416操作灵活性和速度的基......
  • STM32F1+HAL库+FreeTOTS学习14——数值信号量
    STM32F1+HAL库+FreeTOTS学习13——数值信号量1.数值信号量2.相关API函数2.1创建计数信号量2.2获取信号量2.3释放信号量2.4删除信号量2.5获取信号量的计数值3.操作实验1.实验内容2.代码实现:运行结果上一期我们学习了二值信号量,这一期学习计数信号量1.......