Linux进程通信:信号 信号集 信号集函数

news2024/12/24 21:47:53

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/472831.html

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

相关文章

抓马,互联网惊现AI鬼城:上万个AI发帖聊天,互相嗨聊,人类被禁言

近日又有一个社区迷惑走红 上万个AI发帖聊天&#xff0c;人类不得入内&#xff1f; 据红星新闻报道 近日&#xff0c;一个名为Chirper的AI网络社区突然爆火 上万个AI聊天机器人在其中 激烈地聊天、互动、分享 社区主页右上角明确写着&#xff1a; “这是一个人工智能的社交…

《斯坦福数据挖掘教程·第三版》读书笔记(英文版) Chapter 1 Data Mining

来源&#xff1a;《斯坦福数据挖掘教程第三版》对应的公开英文书和PPT Chapter 1 Data Mining Now, statisticians view data mining as the construction of a statistical model, that is, an underlying distribution from which the visible data is drawn. However, ma…

docker上部署程序后无法连接数据库的问题

咱就是说&#xff0c;这个问题差点给我劝退docker。下面说下环境情况。 装了个javaweb程序容器&#xff0c;装了个数据库容器&#xff0c;javaweb容器就是链接不上数据库。 咱也是跟着菜鸟教程的容器互联步骤简历网络链接&#xff1a; 并且启动时增加--networkxxx 都加入到了…

socket通信之select

多线程版本的的socket的server端 #include "socket.hpp" #include <iostream> #include <string> #include <memory>DWORD WINAPI threadProc(LPVOID lp) {SOCKET sClient *(SOCKET*)(lp);while (true) {char buff[1024] { 0 };int result rec…

数据结构初阶 —— 树(堆)

目录 一&#xff0c;堆 堆的概念 向下调整法&#xff08;数组&#xff09; 向上调整法&#xff08;数组&#xff09; 堆的创建&#xff08;建堆&#xff09; 堆的实现 一&#xff0c;堆 堆的概念 如有个关键码的集合K{&#xff0c;&#xff0c;&#xff0c;...&#xf…

Anaconda你不得不知道的若干知识点

Anaconda你不得不知道的若干知识点 1. 查看所有的环境变量2. 加载tensorflow在jupyter中会挂掉怎么办&#xff1f;3. Excel xlsx file&#xff1b; not supported两种解决办法4. (unicode error)5. 统计pandas二维表中的某列的重复值法一&#xff1a;df.loc[:,col_name].value_…

Fabric测试与基础

Fabric官网:Introduction — hyperledger-fabricdocs main documentation 1.测试网络 ./network.sh up #启动./network.sh down #关闭 2.Fabric核心模块 peer:主节点模块&#xff0c;负责存储区块链数据&#xff0c;运行维护链码 orderer:交易打包、排序模块 cryptogen:组织…

【机器学习分支】重要性采样(Importance sampling)学习笔记

重要性采样&#xff08;importance sampling&#xff09;是一种用于估计概率密度函数期望值的常用蒙特卡罗积分方法。其基本思想是利用一个已知的概率密度函数来生成样本&#xff0c;从而近似计算另一个概率密度函数的期望值。 想从复杂概率分布中采样的一个主要原因是能够使用…

uniapp 抖音授权登录、发布、分享 Ba-Aweme

简介&#xff08;下载地址&#xff09; Ba-Aweme 是一个集成抖音的uniapp插件&#xff0c;支持抖音授权登录&#xff0c;发布图片、视频&#xff0c;分享到联系人群组&#xff0c;直接拍摄等。自带选择图片和选择视频方法。 注意&#xff1a; 使用前&#xff0c;先到抖音开放…

LabVIEW CompactRIO 开发指南 3 选择CompactRIO编程模式

第二章 选择CompactRIO编程模式 第一章中介绍的CompactRIO架构为我们提供了通过LabVIEW FPGA定制FPGA硬件或使用NI CompactRIO扫描模式来实现I/O的选项。如果计算机上有LabVIEW Real-Time和LabVIEW FPGA&#xff0c;那么当向LabVIEW项目添加CompactRIO目标时&#xff0c;将提…

BM48-数据流中的中位数

题目 如何得到一个数据流中的中位数&#xff1f;如果从数据流中读出奇数个数值&#xff0c;那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值&#xff0c;那么中位数就是所有数值排序之后中间两个数的平均值。我们使用Insert()方法读取数据流&…

【软考网络管理员】2023年软考网管初级常见知识考点(3)- 网络体系结构

【写在前面】也是趁着五一假期前再写几篇分享类的文章给大家&#xff0c;希望看到我文章能给软考网络管理员备考的您带来一些帮助&#xff0c;5月27号也是全国计算机软件考试统一时间&#xff0c;也就不用去各个地方找资料和代码了。紧接着我就把我整理的一些资料分享给大家哈&…

【Python】selenium工具

目录 1. 安装 2. 测试 3. 无头浏览器 4. 元素定位 5. 页面滑动 6. 按键、填写登录表单 7. 页面切换 Selenium是Web的自动化测试工具&#xff0c;为网站自动化测试而开发&#xff0c;Selenium可以直接运行在浏览器上&#xff0c;它支持所有主流的浏览器&#xff0c;可以接…

【Linux - Shell常用命令】- 判断文件是否存在、去掉文件后缀

目录 一、判断文件是否存在1.1 判断目录是否存在1.2 判断文件是否存在1.3 其他文件类型判断 二、字符串截取&#xff08;去掉文件后缀&#xff09;2.1 获取文件后缀2.2 获取文件前缀 一、判断文件是否存在 1.1 判断目录是否存在 将下面代码保存为dirExist.sh &#xff0c;运行…

隐私权限是什么

导读&#xff1a; 隐私权在现代社会对于人们而言是重要的人格权&#xff0c;而随着互联网技术的发展&#xff0c;实践中侵犯隐私权的行为很常见。那么隐私权限是什么&#xff1f;侵犯隐私权的行为有哪些&#xff1f;侵犯他人隐私权要负什么法律责任&#xff1f;接下来将由找法…

Linux-修改虚拟机为静态IP 和 主机名

一、设置虚拟机的IP为静态的 一般情况下&#xff0c;NAT网络连接模式下&#xff0c;DHCP动态分配IP地址的&#xff0c;但这样在每次访问连接Linux虚拟机时&#xff0c;都要先去查询ip地址&#xff0c;很麻烦&#xff0c;干脆就将虚拟机IP地址写死&#xff0c;也就是设置为静态…

数据结构初阶 —— 树(二叉树)

目录 一&#xff0c;二叉树 特殊二叉树 二叉树的性质 二叉树的存储结构 二&#xff0c;二叉树链式结构 二叉树的遍历&#xff08;四种&#xff09; 二叉树接口 试题 一&#xff0c;二叉树 由一个根节点&#xff0c;加上两颗左二叉树和右二叉树组成&#xff0c;可以为空…

python cms建站教程:Wagtail建站(一、安装与基本使用)

最近有个建站的项目&#xff0c;因为python比较熟&#xff0c;为了快速建站想着用cms&#xff0c;但发现网上关于python cms的教程很少&#xff0c;于是自己试着写一个。建站工具采用Wagtail&#xff0c;是一款基于Django框架的cms&#xff0c;自己照着文档摸索了一番&#xff…

线性调频Z变换 CZT

文章目录 【1. 原理】【2. z k z_k zk​ 所在的路径】【3. CZT的实现步骤】【4. CZT的特点 】【5. CZT的应用】5.1 通过 CZT 变换求 DFT5.2 对信号的频谱进行细化分析5.3 求解Z变换X(z)的零、极点5.4 使用CZT进行Keystone变换 【6.相关文献】 线性调频Z变换&#xff08;chirp …

FL Studio中文版V21的主要功能与下载教程

FL Studio21最新版是流行的数字音频工作站(DAW)其最新版本FL Studio 21,主要功能和下载教程如下: FL Studio21中文版功能介绍: 1. 全新界面:采用简洁现代的设计风格,工具栏和菜单进行重组,更加直观。提供智能提示与工作流指导,易于学习和操作。 2. 多显示器支持:可以在不同屏…