Linux信号:信号 信号集 信号集函数

news2024/11/22 13:17:55

1. 信号的概念

Linux进程间通信的方式之一。信号也称为“软件中断”。

信号特点:

  • 简单;
  • 携带信息有限;
  • 满足特定条件才发送信号;
  • 可进行用户空间和内核空间进程的交互;

信号4要素:

(1)编号;(2)名称;(3)事件;(4)默认处理方式。


2. 信号的编号

kill -l   // 查看信号编号

POSIX信号标准: 

 1~31为常规信号;34~64为实时信号(驱动编程、硬件相关)。

为保证代码可移植性,请使用信号名进行编程。


Linux常规信号介绍:

编号信号事件默认处理
1SIGHUP用户退出shell时,由该shell启动的所有进程会收到SIGHUP信号。终止进程
2SIGINTCtrl + c 触发该信号,由该终端启动的正在运行的进程会收到SIGINT信号。终止进程
3SIGQUITCtrl + \ 触发该信号,由该终端启动的正在运行的进程会收到SIGQUIT信号。终止进程
4SIGILLCPU检测到某些进程执行非法指令。终止进程并产生core文件
5SIGTRAP由断点指令或其他trap指令产生。终止进程并产生core文件
6SIGABRT调用abort函数时产生该信号。终止进程并产生core文件
7SIGBUS非法访问内存地址、内存对齐出错。终止进程并产生core文件
8SIGFPE发生致命运算错误。浮点运算错误、溢出、除数为0等。终止进程并产生core文件
9SIGKILL无条件终止进程。该信号不能被忽略、处理、阻塞。终止任意进程
10SIGUSE1用户定义的信号。程序员可在程序中定义并使用该信号。终止进程
11SIGSEGV进程进行了无效内存访问(段错误)。终止进程并产生core文件
12SIGUSR2用户定义的信号。程序员可在程序中定义并使用该信号。终止进程
13SIGPIPEBroken pipe向一个无读端的管道写数据。终止进程
14SIGALRM定时器超时,超时时间由系统调用alarm设置。终止进程
15SIGTERM终止进程,该信号可被阻塞、终止。通常用来通知程序正常退出。kill命令的缺省选项就是这个信号。终止进程
16SIGSTKFLTLinux早期版本的信号,使用极少。终止进程
17SIGCHLD子进程结束时,父进程会收到该信号。忽略
18SIGCONT使暂停的进程继续运行继续/忽略
19SIGSTOP暂停进程。不能被忽略、处理、阻塞。暂停进程
20SIGTSTPCtrl + z 触发该信号,暂停与终端交互的进程。暂停进程
21SIGTTIN后台进程读终端控制台暂停进程
22SIGTTOU类似于SIGTTIN,后台进程向终端输出数据时触发暂停进程
23SIGURGsocket上有紧急数据时,向当前进程发出该信号忽略
24SIGXCPU进程执行时间超过CPU时间的总量。(不是超过了时间片)终止进程
25SIGXFSZ超过文件最大长度终止进程
26SIGVTALRM虚拟时钟产生的信号,类似于SIGALRM。该信号3计算该进程占用CPU的时间终止进程
27SIGPROF类似于SIGVTALRM,计算进程占用CPU时间 + 系统调用时间终止进程
28SIGWINCH窗口大小变化时触发忽略
29SIGIO向进程发出一个异步IO事件忽略
30SIGPWR关机终止进程
31SIGSYS无效的系统调用终止进程并产生core文件
31~64SIGRTMIN~SIGRTMAXLinux实时信号,无固定含义,可由用户自定义终止进程

3. 信号的状态 

(1)产生状态

        a)用户发出信号:

                Ctrl + c :SIGINT;

                Ctrl + \  :SIGQUIT;

                Ctrl + z  :SIGSTOP;

        b)硬件异常:

                除数为0、无效内存访问、溢出等,被硬件检测到通知内核,内核将对应的信号发给相应进程。

        c)软件异常:

                检测到某种软件信号(如定时器alarm),则通知相关进程。

        d)系统调用:

                如kill、raise、abort等系统调用会发出信号。

               注意:接收信号进程与发送信号进程的所有者必须相同,或发送信号进程的所有者是root用户。

        e)kill、killall等会发送信号。

(2)未决状态:信号未被处理。

(3)递达状态:信号被处理了。


4. 阻塞信号集 & 未决信号集

每个进程的PCB中有两个信号集合:阻塞信号集 & 未决信号集。

两个集合都是用位图表示信号的状态,1表示阻塞或未决。

仅可设置阻塞信号集;未决信号集由内核自动设置。

(1)阻塞信号集:

        将某信号加入该阻塞信号集,该信号将被阻塞;

        若被阻塞期间收到该信号,则不会被处理;

        但在解除阻塞后,阻塞期间收到的那次信号仍然会被处理,相当于滞后处理该信号。

(2)未决信号集:

        某信号产生,未决信号集中描述该信号的状态位被置为1,表示该信号为未决状态;当信号被处理,该信号对应的状态位被置为0。

        信号产生后由于某些原因(主要为被阻塞)不能抵达,这些信号状态为未决状态。

        信号被阻塞期间,一直处于未决状态。


5. 信号集函数

(1)信号集操作函数

#include<signal.h>

int sigemptyset(sigset_t* set);           // 将set信号集置空
int sigfillset(sigset_t* set);            // 将所有信号加入set信号集
int sigaddset(sigset_t* set, int signo);  // 将signo信号加入set信号集
int sigdelset(sigset_t* set, int signo);  // 将signo信号从set信号集移除
int sigismember(const sigset_t* set, int signo); // 判断set信号集中是否存在signo信号

/*sigset_t为二进制位图*/

信号集操作函数使用示例:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<signal.h>
#include<unistd.h>

void showSet(sigset_t* set) { // 显示信号集
    for (int i = 1; i < 32; i++) {
        if (sigismember(set, i)) {
            printf("1");
        } else {
            printf("0");
        }
    }
    putchar('\n');
}

int main(int argc, const char* argv[]) {

    int i = 0;

    // 定义信号集
    sigset_t set;

    // 清空信号集
    sigemptyset(&set);
    puts("sigemptyset后的信号集:");
    showSet(&set);

    // 将所有的信号加入信号集
    sigfillset(&set);
    puts("sigfillset后的信号集:");
    showSet(&set);

    // 将信号1,3从信号集中移除
    sigdelset(&set, SIGHUP);
    sigdelset(&set, SIGQUIT);
    puts("sigdelset后的信号集:");
    showSet(&set);

    // 将信号1,3加入信号集
    sigaddset(&set, SIGHUP);
    sigaddset(&set, SIGQUIT);
    puts("sigaddset后的信号集:");
    showSet(&set);

    return 0;
}

运行结果:


 (2)sigprocmask函数

#include<signal.h>

int sigprocmask(int how, const sigset_t* set, sigset_t* oldset);
/*
功能:
    根据how指定的方法对进程的阻塞信号集进行操作。
    新的阻塞信号集由set指定,原先的阻塞信号集由oldset保存。

参数:
    how:对阻塞信号集的操作方式:
        SIG_BLOCK:向阻塞信号集中添加set信号集,新的信号集是set与oldset的并集。
                   相当于mask = mask | set;
        SIG_UNBLOCK:从阻塞信号集中删除set集合。
                     相当于mask = mask & ~set;
        SIG_SETMASK:将阻塞信号集设置为set。
                     相当于mask = set;

    set:要操作的信号集地址。
         若为NULL,则不改变阻塞信号集。仅将当前的阻塞信号集保存到oldset中。
    
    oldset:保存原先阻塞信号集的地址。

返回值:
    成功:0
    失败:-1,失败时错误码只可能是EINVAL,表示参数how不合法。  
*/

sigprocmask示例:

屏蔽SIGINT(Ctrl + C)信号。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<signal.h>
#include<unistd.h>

void func0(int signum) {
    printf("捕捉到信号:%d\n", signum);
}

void func1(int signum) {
    printf("捕捉到信号:%d\n", signum);
}

int main(int argc, const char* argv[]) {

    int ret = -1;

    // 信号集
    sigset_t set;
    sigset_t old;

    /*注册信号处理函数。*/
    // SIGINT: Ctrl + c  2号信号
    signal(SIGINT, func0);

    /*SIGQUIT: Ctrl + \*/
    signal(SIGQUIT, func1);

    /*将SIGINT加入阻塞信号集*/
    printf("按回车键阻塞信号2 SIGINT.\n");

    // 只能输入回车,输入一个字符再回车,就相当于输入两个字符;第二个回车被下面的getchar接收。
    getchar();

    sigemptyset(&set); // 清空信号集
    sigaddset(&set, SIGINT); // 将2号信号加入信号集
    sigemptyset(&old); // 清空信号集
    ret = sigprocmask(SIG_BLOCK, &set, &old); // 设置阻塞信号集
    if (-1 == ret) {
        perror("sigprocmask");
        return 1;
    }
    printf("2号信号SIGINT屏蔽成功.\n");
    printf("按下回车键解除2号信号的屏蔽.\n");

    getchar();

    /*将阻塞信号集设置为原先的集合*/
    ret = sigprocmask(SIG_SETMASK, &old, NULL);
    if (-1 == ret) {
        perror("sigprocmask");
        return 1;
    }

    getchar();

    return 0;
}

运行结果:

  


(3)sigpending函数

获取未决信号集

#include<signal.h>

int sigpending(sigset_t* set);
/*
功能:
    获取未决信号集存入set集合
参数:
    set:存储未决信号集
返回值:
    成功:0
    失败:-1
*/

sigpending示例:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<signal.h>
#include<unistd.h>

int main(int argc, const char* argv[]) {

    int ret = -1;
    sigset_t new;
    sigset_t old;
    sigset_t set;

    sigemptyset(&new); // 清空信号集set
    sigemptyset(&old); // 清空信号集set
    sigemptyset(&set); // 清空信号集set
    /*将信号2、3放入信号集*/
    sigaddset(&new, SIGINT);
    sigaddset(&new, SIGQUIT);

    ret = sigprocmask(SIG_BLOCK, &new, &old); // 将信号2、3放入阻塞信号集
    if (-1 == ret) {
        perror("sigprocmask");
        return 1;
    }

    getchar();

    ret = sigpending(&set); // 获取阻塞信号集
    if (-1 == ret) {
        perror("sigpending");
        return 1;
    }

    for (int i = 1;i < 32;i++) { // 打印阻塞信号集
        if (sigismember(&set, i)) {
            printf("%d ", i);
        }
    }
    putchar('\n');

    return 0;
}

将信号2、信号3加入阻塞信号集后,按Ctrl + c、Ctrl + \ ,被阻塞,之后解除阻塞会捕捉到信号2、信号3.

运行结果:

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

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

相关文章

根据Java的TreeMap源码的原理编写C++红黑树删除操作

&#xff08;一&#xff09;了解二叉搜索树的删除操作 删除操作总结&#xff1a; ******普通结点删除&#xff1a;******* ①删除叶结点 ②删除只有1个子结点的结点 >>如果被删除结点的左子树为空&#xff0c;则令其右子树子承父业代替其位置即可 >>如果被删除结点…

JPA整合达梦数据库

陈老老老板&#x1f9b8; &#x1f468;‍&#x1f4bb;本文专栏&#xff1a;国产数据库-达梦数据库&#xff08;主要讲一些达梦数据库相关的内容&#xff09; &#x1f468;‍&#x1f4bb;本文简述&#xff1a;本文讲一下SpringBoot整合JPA与达梦数据库&#xff0c;就是简单&…

《算法工程师带你去》读书笔记

什么是稀疏向量&#xff08;向量的稀疏表示&#xff09; 对数据进行预处理时&#xff0c;一般需要对类别型特征进行编码&#xff1a; 序号编码独热编码 二进制编码 其中独热编码用的是最多的。但是当类别数十分巨大时&#xff0c;独热编码是一个非常稀疏的向量&#xff0c;只有…

IDEA(八)常用插件推荐

目录 1.GitHub Copilot2.MyBatisCodeHelperPro3.Maven Helper4.Translation5.Api Savior6.Alibaba Java Coding Guidelines7.Sequence Diagram8.Key Promoter X9.Restfultoolkit-fix 在IDEA中&#xff0c;Ctrl Alt S 选择 Plugins&#xff0c;可以添加很多帮助我们开发的插件…

Arduino串口提取数字(整型和浮点型)

数据提取 文章目录 数据提取前言一、提取整型数据二、提取浮点型数据 前言 之前需要用32和ESP进行通信上传数据&#xff0c;一直都用的都是数据上传然后处理成整型数据&#xff0c;今天需要处理成浮点型数据所以就查了一下&#xff0c;于是就记录一下。 一、提取整型数据 #i…

〖Python网络爬虫实战⑳〗- 数据存储之CSV操作实战

订阅&#xff1a;新手可以订阅我的其他专栏。免费阶段订阅量1000 python项目实战 Python编程基础教程系列&#xff08;零基础小白搬砖逆袭) 说明&#xff1a;本专栏持续更新中&#xff0c;目前专栏免费订阅&#xff0c;在转为付费专栏前订阅本专栏的&#xff0c;可以免费订阅付…

JDBC数据库连接技术学习笔记

1. 概述 本笔记是学习尚硅谷教育的23版jdbc的课后笔记 1.1 JDBC概念和理解 1. jdbc是(Java Database Connectivity)单词的缩写,翻译为java连接数据库 2. jdbc是java程序连接数据库的技术统称 3. jdbc由java语言的规范(接口)和各个数据库厂商的实现驱动(jar)组成 4. jdbc是一…

Mysql 判断语句

目录 5 判读 5.1 if ... then ...->示例演示 局部变量 -> 打包储存过程 5.2 case 5.2.1 语法一 5.2.2 语法二 -> 示例演示 5.3 while 循环 ->有条件循环 5.3.1 示例演示 5.4 repeat 循环 -> 满足条件 -> 退出循环 5.4.1 示例演示 5.5 loop 5.5.1…

【c语言小项目】基于easyX的俄罗斯方块

EeayX是针对 C/C 的简单图形库插件&#xff0c;本项目基于easyX游戏框架下实现俄罗斯方块游戏。 俄罗斯方块功能实现中主要运用了二维数组的循环遍历。能够实现基本功能&#xff0c;暂未实现旋转 c语言系列专栏&#xff1a;c语言之路重点知识整合 更多相关&#xff1a;c语…

AI VS 好莱坞?新时代电影工作流;MJ制作微信表情包的麻瓜教程;关于ControlNet的一切;AI创业真钱景 | ShowMeAI日报

&#x1f440;日报&周刊合集 | &#x1f3a1;生产力工具与行业应用大全 | &#x1f9e1; 点赞关注评论拜托啦&#xff01; &#x1f916; 『OpenAI通过了一大批GPT-4申请』大量放号ing~快去看邮箱&#xff01; &#x1f916; 『小马智行 | 广州南沙区开启车内无安全员的自动…

opencv-python加载pytorch训练好的onnx格式线性回归模型

opencv是一个开源的图形库&#xff0c;有针对java,c,python的库依赖&#xff0c;它本身对模型训练支持的不好&#xff0c;但是可以加载其他框架训练的模型来进行预测。 这里举一个最简单的线性回归的例子&#xff0c;使用深度学习框架pytorch训练模型&#xff0c;最后保存模型为…

【软考备战·希赛网每日一练】2023年4月28日

文章目录 一、今日成绩二、错题总结第一题第二题第三题 三、知识查缺 题目及解析来源&#xff1a;2023年04月28日软件设计师每日一练 一、今日成绩 二、错题总结 第一题 解析&#xff1a; 大体了解即可&#xff0c;题目要考察的核心意思&#xff1a;确定的有限自动机和不确定的…

js 操作数组内容

js 操作数组内容 数组添加元素&#xff08;更改原数组&#xff09; push和unshift会返回添加了新元素的数组长度 push从数组最后加入&#xff0c;unshift从数组最前面加入 const arr ["a", "b", "c"]; arr.push("d"); //返回4…

数据结构基础day9

题目&#xff1a;187. 重复的DNA序列 解法1&#xff1a;哈希表 class Solution { public:vector<string> findRepeatedDnaSequences(string s) {vector<string> ans;unordered_map<string, int> mp;int ns.size(), L10;for(int i0; i<n-L; i){ //从开头…

【fluent UDF】warning: unused variable警报:存在未使用的变量

一、问题背景 在编译UDF时&#xff0c;出现如下错误 curing_heat_v3.c: In function ‘iter_ending’: curing_heat_v3.c:105:14: warning: unused variable ‘volume_sum’ [-Wunused-variable] real volume_sum0.0; curing_heat_v3.c:104:14: warning: unused variable ‘…

【Python零基础学习入门篇②】——第二节:Python的常用语句

⬇️⬇️⬇️⬇️⬇️⬇️ ⭐⭐⭐Hello&#xff0c;大家好呀我是陈童学哦&#xff0c;一个普通大一在校生&#xff0c;请大家多多关照呀嘿嘿&#x1f601;&#x1f60a;&#x1f618; &#x1f31f;&#x1f31f;&#x1f31f;技术这条路固然很艰辛&#xff0c;但既已选择&…

网络编程之简单socket通信

一.什么是Socket? Socket&#xff0c;又叫套接字&#xff0c;是在应用层和传输层的一个抽象层。它把TCP/IP层复杂的操作抽象为几个简单的接口供应用层调用以实现进程在网络中通信。 socket分为流socket和数据报socket&#xff0c;分别基于tcp和udp实现。 SOCK_STREAM 有以下…

苦学58天,最后就这结果......

背景 非计科大专一枚&#xff0c;当初学的机械自动化专业。大学完全可以说是玩过来的&#xff0c;临近毕业开始慌了&#xff0c;毕业后一直没能找到工作&#xff0c;在高中同学&#xff08;211 计科&#xff09;的引领下&#xff0c;入坑程序员&#xff0c;学的软件测试。 从…

Lombok简介

Lombok简介 1、lombok简介2、springboot整合lombok 1、lombok简介 Lombok是一个第三方的Java工具库&#xff0c;会自动插入编辑器和构建工具。Lombok提供了一组非常有用的注解&#xff0c;用来消除Java类中的大量样板代码&#xff0c;比如setter和getter方法、构造方法等。只需…

Vue(简单了解Cookie、生命周期)

一、了解Cookie 类似于对象响应携带数据 输入用户名密码跳转到指定页面 点击指定页面中其中一个按钮跳转到另一个指定页面&#xff08;再不需用输入用户名密码&#xff09; 例如现在很多浏览器实现七天免密登录 简单理解&#xff1a;就是在网站登录页面之后&#xff0c;服务…