Linux-信号2

news2024/11/23 1:53:27

文章目录

  • 前言
  • 一、信号是如何保存的?
    • 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);
    • int sigpending(sigset_t *set);
    • int sigprocmask(int how, const sigset_t *set, sigset_t *oset);
      • 1.SIG_BLOCK
      • 2.SIG_UNBLOCK
      • 3.SIG_SETMASK
  • 二、学习步骤
    • 我们提出三个问题并对问题进行一一解答来进行我们的学习
      • 问题1. 如果我们将一个死循环进程的所有信号都捕捉,是不是该进程无法被退出?
      • 问题2. 如果我们将一个信号block阻塞,并发送对应信号,pending表的对应该信号bit位是不是由0置1?
      • 问题3. 如果我们将一个死循环进程的所有信号都阻塞,是不是该进程也无法被退出?
    • 1.解答问题1
    • 2.解答问题2
    • 3.解答问题3


前言

上节课我们学习了信号产生到处理过程的现象以及信号的捕捉,这节课主要学习信号的保存。
我们需要熟练使用以下函数

#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);
int sigprocmask(int how, const sigset_t *set, sigset_t *oset);
int sigpending(sigset_t *set);


一、信号是如何保存的?

上节课我们说过,信号是在进程的PCB中存储 信号的位图,而实际上,可不止有一个表(位图)。
在这里插入图片描述

block信号集是用以保存被block阻塞的信号,一般被称为信号屏蔽字(阻塞信号集),pending信号集就是我们上节课所说的那个收到信号即相对位由0置1的位图,一般被称为未决信号集

对于阻塞,这是提前预设好的,目的是为了让该进程屏蔽该信号,所以如果一个信号被阻塞,而又收到了该信号,虽然pending信号集由0置1,但是不进行delivery(信号递达:信号递达操作即信号的处理)操作。

而这两个信号集,在我们看来理解其实就是位图,但是OS将他们封装成了自定义类型sigset_t,通过这样的封装,对于我们用户就无法随心所欲地更改其信号集的数据,只能通过OS提供给我的系统接口函数。
现在来认识一下系统交给我们的一些接口函数。

int sigemptyset(sigset_t *set);

函数sigemptyset初始化set所指向的信号集,使其中所有信号的对应bit清零,表示该信号集不包含 任何有
效信号。
成功返回0,出错返回-1

int sigfillset(sigset_t *set);

函数sigfillset初始化set所指向的信号集,使其中所有信号的对应bit置位,表示 该信号集的有效信号包括系
统支持的所有信号。
成功返回0,出错返回-1

int sigaddset (sigset_t *set, int signo);

函数sigaddset用于将set所指向的信号集的signo信号置位。
成功返回0,出错返回-1

int sigdelset(sigset_t *set, int signo);

函数sigdelset用于将set所指向的信号集的signo信号置零。
成功返回0,出错返回-1

int sigismember(const sigset_t *set, int signo);

函数sigismember用于判断set所指向信号集的signo信号是否为1。
是则返回1,否则为0。

int sigpending(sigset_t *set);

函数sigpending用于读取当前进程的未决信号集,通过set参数传出。
调用成功则返回0,出错则返回-1。

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

函数sigprocmask用于更改block信号集,参数how为选项,该函数提供三种选项

1.SIG_BLOCK

该选项是希望在目前的信号屏蔽字添加set信号集的有效信号,相当于mask=mask|set

2.SIG_UNBLOCK

该选项是希望在目前的信号屏蔽字去除set信号集的有效信号,相当于mask=mask&(~set)

3.SIG_SETMASK

该选项就比较暴力些,相当于mask=set

而参数oset为输出型参数,用于保存老信号集。

需要注意的,在使用sigset_ t类型的变量之前,一定要调 用sigemptyset或sigfillset做初始化,使信号集处于确定的
状态。

二、学习步骤

我们提出三个问题并对问题进行一一解答来进行我们的学习

问题1. 如果我们将一个死循环进程的所有信号都捕捉,是不是该进程无法被退出?

问题2. 如果我们将一个信号block阻塞,并发送对应信号,pending表的对应该信号bit位是不是由0置1?

问题3. 如果我们将一个死循环进程的所有信号都阻塞,是不是该进程也无法被退出?

1.解答问题1

代码如下(示例):

#include<stdio.h>
#include<unistd.h>
#include<iostream>
#include<signal.h>

void catchSig(int signum)
{
    std::cout << "pid " << getpid() <<" :捕捉到信号 " << signum << std::endl; 
}

int main()
{
    for(int i = 1; i <= 31 ; i++)
    {
        signal(i,catchSig);
    }

    while(1)
    {
        std::cout << "pid " << getpid() << " :进程运行中... " <<std::endl;
        sleep(1);
    }
    return 0;
}

这个程序会在运行时捕捉1-31号的所有信号,那么是不是这个进程就无法退出了呢?
我们通过命令行依次输入kill命令来进行对该进程发送信号,发现在发送9号信号的时候,进程还是被终止了,说明进程的9号信号没有被捕捉!
在这里插入图片描述
所以这里的结论就是如果我们将一个死循环进程的所有信号都捕捉,该进程仍然可以通过9号信号退出,因为设计OS的人知道,如果有恶意程序真的将所有信号都可以捕捉,那么后果是十分严重的!

2.解答问题2

代码如下(示例):

#include <stdio.h>
#include <unistd.h>
#include <iostream>
#include <signal.h>
#include <assert.h>

void ShowSet(sigset_t &set)
{
    for (int i = 1; i <= 31; i++)
    {
        // 通过sigismember来打印我们的pending信号集
        std::cout << sigismember(&set, i);
    }
    std::cout << std::endl;
}

int main()
{
    sigset_t set;
    sigset_t block;
    sigset_t oset;
    // 1.进行初始化
    sigemptyset(&set);
    sigemptyset(&block);
    sigemptyset(&oset);

    // 2.阻塞2号信号
    sigaddset(&block, 2);
    sigprocmask(SIG_BLOCK, &block, &oset);

    std::cout << "pid " << getpid() << std::endl;
    // 3.循环打印未决信号集
    while (1)
    {
        // 3.1 获取当前的未决信号集
        sigpending(&set);
        ShowSet(set);
        sleep(1);
    }
    return 0;
}

在这里插入图片描述
我们很清楚的看到第二位由0置1了。
所以结论就是如果我们将一个信号block阻塞,并发送对应信号,pending表的对应该信号bit位是由0置1。

3.解答问题3

代码如下(示例):

#include <stdio.h>
#include <unistd.h>
#include <iostream>
#include <signal.h>
#include <assert.h>

void ShowSet(sigset_t &set)
{
    for (int i = 1; i <= 31; i++)
    {
        // 通过sigismember来打印我们的pending信号集
        std::cout << sigismember(&set, i);
    }
    std::cout << std::endl;
}

void SendSig(int signum)
{
    if ((signum != 19) &&(signum != 9) && (signum <= 31))
        raise(signum);
}

int main()
{
    sigset_t set;
    sigset_t block;
    sigset_t oset;
    // 1.进行初始化
    sigemptyset(&set);
    sigemptyset(&block);
    sigemptyset(&oset);

    // 2.阻塞所有信号
    for (int i = 1; i <= 31; i++)
    {
        sigaddset(&block, i);
    }
    sigprocmask(SIG_SETMASK, &block, &oset);

    // 3.循环打印未决信号集
    int count = 1;
    while (1)
    {
        // 3.1 获取当前的未决信号集
        sigpending(&set);
        ShowSet(set);
        SendSig(count++);
        sleep(1);
    }
    return 0;
}

在这里插入图片描述
我们看到这样的情况,可以得出看出9号信号和19号信号是不可屏蔽的!

所以这里的结论就是如果我们将一个死循环进程的所有信号都屏蔽,该进程仍然可以通过9号信号退出。


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

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

相关文章

记录些大语言模型(LLM)相关的知识点

槽位对齐&#xff08;slot alignment&#xff09; 在text2sql任务中&#xff0c;槽位对齐&#xff08;slot alignment&#xff09;通常指的是将自然语言问题中的关键信息&#xff08;槽位&#xff09;与数据库中的列名或API调用中的参数进行匹配的过程。这个过程中&#xff0c…

C++--机器人的运动范围

目录 1. 题目 2. 思路 3. C代码测试 4. 测试结果 1. 题目 地上有一个m行和n列的方格。一个机器人从坐标0,0的格子开始移动&#xff0c;每一次只能向左&#xff0c;右&#xff0c;上&#xff0c;下四个方向移动一格&#xff0c;但是不能进入行坐标和列坐标的数位之和大于k的格…

xss.haozi.me:0x09

https://www.segmentfault.com.haozi.me/j.js

MySQL 多表查询 连接查询 自连接

介绍 自连接查询&#xff0c;可以是内连接查询&#xff0c;也可以是外连接查询&#xff0c;一句话自己连接自己&#xff0c;一个表当作两个表进行连接。 语法 SELECT 字段列表 FROM 表A 别名A JOIN 表A 别名B ON 条件两个表A说明是同一张表&#xff0c;但是别名不同 案例…

Ubuntu环境使用docker构建并运行SpringBoot镜像

今天Ubuntu环境使用docker构建并运行SpringBoot镜像&#xff0c;看文章之前建议先查看安装流程: Linux环境之Ubuntu安装Docker流程 一、镜像打包过程及执行 1、创建一个测试目录 mkdir javaDemo 2、springBoot的包复制到此目录下 cp demo1-0.0.1-SNAPSHOT.jar /data/app/…

【源码】imx6ull实现触摸屏单点实验-移植tslib和qt

一、本实验实验的器材&#xff1a; 1.正点原子imx6ull的阿尔法开发板v2.2 2.屏幕ALIENTEK 4.3 RGBLCD 二、实验已经移植好的文件&#xff1a; 仓库代码&#xff1a;https://gitee.com/wangyoujie11/atkboard_-linux_-driver.git 1.文件说明 arm-qt.tar.bz2&#xff1a;移植好的…

SwiftUI中Alert与ActionSheet的集成

在SwiftUI中&#xff0c;Alert和ActionSheet是两个用于显示提示信息和选项的组件。Alert用于显示简单的提示信息&#xff0c;而ActionSheet用于显示多个选项供用户选择。 要在SwiftUI中使用Alert&#xff0c;首先需要在视图中定义一个State属性来存储是否显示Alert&#xff0c…

持续集成(CICD)- gogs仓库的部署和使用

文章目录 一、gogs的介绍二、部署gog仓库三、首次启动gogs四、登录五、创建一个非空仓库六、从仓库拉取代码到本地七、把本地编辑的代码上传到仓库 一、gogs的介绍 Gogs作为一个轻量级、易于部署和使用的自托管Git服务&#xff0c;为小型团队和个人开发者提供了一个简单而强大…

QT实现Ftp客户端的三种方法及工程实例

1.Qt项目中实现的FTP传输功能的三种方式 &#xff08;1&#xff09;QFtp QFtp 是 Qt4 中专门负责 FTP 传输的类&#xff0c;包括创建目录、删除目录、删除文件、获取文件列表、上传、下载等等常规操作。 注意&#xff1a;QT5中已经移除&#xff0c;如果需要用需要自己添加QFtp…

day6 数组 嵌套循环

1&#xff1a;打印杨辉三角 91 int arr[6][6];92 int i,j0;93 for(i0;i<6;i)94 {95 for(j0;j<i;j) 96 {97 if(j0||ij)98 {99 arr[i][j]1; …

2.3 shl,shr,inc,dec,xchg,neg指令,中断int指令

汇编语言 1. shl左移指令 shl是逻辑左移指令&#xff0c;它的功能是将一个reg或内存单元中的数据向左移位&#xff1b;将最后移出的一位写入cf中&#xff1b;最低位用0补充shl&#xff1a;shift left例如&#xff1a;0100 1000b 往左移一位&#xff0c;变成10010000b&#xf…

Vue.js中的diff算法:让虚拟DOM更高效

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

C++ Primer Plus Sixth Edition - 下载电子书与源代码

C Primer Plus Sixth Edition - 下载电子书与源代码 1. C Primer Plus, 6th Edition1.1. Download the source code files1.2. 下载源代码文件 2. C Primer Plus, Sixth Edition (PDF)3. Table of ContentsReferences 1. C Primer Plus, 6th Edition C Primer Plus, 6th Editi…

xss.haozi.me:0x02

"><script>alert(1)</script> 这样就成功了

07. Nginx进阶-Nginx负载均衡

简介 负载均衡 什么是负载均衡&#xff1f; 负载均衡&#xff0c;英文名称为Load Balance&#xff0c;其含义就是指将负载&#xff08;工作任务&#xff09;进行平衡、分摊到多个操作单元上进行运行。 Nginx负载均衡 什么是Nginx负载均衡&#xff1f; Nginx负载均衡可以大…

redis07 持久化(RDB、AOF)

思维草图 redis持久化认识 Redis是一个基于内存的数据库&#xff0c;它的数据是存放在内存中&#xff0c;内存有个问题就是关闭服务或者断电会丢失。 Redis的数据也支持写到硬盘中&#xff0c;这个过程就叫做持久化。 Redis提供了2种不同形式的持久化方式。 RDB&#xff08…

安全团队官网介绍页源码

安全团队官网介绍页源码&#xff0c;源码由HTMLCSSJS组成&#xff0c;记事本打开源码文件可以进行内容文字之类的修改&#xff0c;双击html文件可以本地运行效果&#xff0c;也可以上传到服务器里面 下载地址 https://www.qqmu.com/2383.html

Unity 角色控制(初版)

角色控制器组件&#xff0c;当然是将组件放在角色上了。 using System.Collections; using System.Collections.Generic; using UnityEngine;public class c1 : MonoBehaviour {// 获取角色控制器private CharacterController player;void Start(){// 加载角色控制器player …

【自然语言处理六-最重要的模型-transformer-下】

自然语言处理六-最重要的模型-transformer-下 transformer decoderMasked multi-head attentionencoder和decoder的连接部分-cross attentiondecoder的输出AT(Autoregresssive)NAT transformer decoder 今天接上一篇文章讲的encoder 自然语言处理六-最重要的模型-transformer-…

红黑树的简单介绍

红黑树 红黑树的概念 红黑树&#xff0c;是一种二叉搜索树&#xff0c;但在每个结点上增加一个存储位表示结点的颜色&#xff0c;可以是Red或Black。 通过对任何一条从根到叶子的路径上各个结点着色方式的限制&#xff0c;红黑树确保没有一条路径会比其他路径长出俩倍&#x…