Linux进程信号(上)

news2025/2/20 23:20:19

目录

一:信号引入

二:信号保存方式

三:信号处理方式

四:查看Linux信号

五:信号捕捉

六:信号产生

一:终端按键产生信号 

二:系统函数产生信号

2.1:kill()

2.2:raise()

2.3:abort() 

三:软件条件产生信号


一:信号引入

生活中有很多信号:红绿灯,闹钟,警灯,外卖员的电话等等。把这些称作信号是有一个共同特点:接收到这些信号后,会执行一个动作。因此我们引出Linux中的信号。

1:为什么会执行这个动作?说明我们(进程)可以识别这个信号。

2:我们识别到信号,能够做出对应的动作。说明我们(进程)可以处理信号。

3:当我们在打游戏时接收到外卖员电话,我们可能会说等一等,我过会去拿。这说明信号可能随时产生,我们(进程)会记录信号。

4:在我们让外卖员等一等的时候,我们仍然在干别的事情,说明我们(进程)在识别信号---处理信号之间有个时间窗口。

5:整个拿外卖的过程是异步的,也就是说进程信号的产生是异步的。(因为进程执行到任何地方,都有可能接收SIGINT而终止)

二:信号保存方式

在系统中一定会产生多个进程,对多个进程发信号,就要把这么多信号保存起来,因此采用先描述再组织的方法。

Linux中采用位图,用0和1表示信号的有无,通过不同的比特位为1表示不同的信号。

所谓的发信号就是写入信号,修改特定进程的位图中对应的比特位为1。而这种task_struct数据内核结构,只能由OS来修改。无论有多少信号写入进程,最后都是由OS来完成最后的发送过程。

三:信号处理方式

  • 默认动作
  • 忽略信号
  • 用户自定义动作

四:查看Linux信号

之前我们学进程章节有用过kill -9来杀死一个进程,现在可以用kill -l查看信号。

共61个信号,没有0信号,32信号,33信号。

1--31信号为普通信号。

34-64信号为实时信号。

通过man 7 signal查看详细的信号信息:

 

 

Term:正常退出

Core:异常退出,可以使用核心转储功能定位错误(core dump)

Lgn:内核级忽略 

2)SIGINT  终止信号,即键盘输入ctrl+c
3)SIGQUIT 终止信号,即键盘输入ctrl+\
6)SIGABRT 终止信号  调用abort即可收到该信号
8)SIGFPE  终止信号  除0错误即可收到该信号
11)SIGSEGV 终止信号 段错误即可收到该信号
13)SIGPIPE 终止信号 匿名管道读端关闭,写端即可收到该信号
14)SIGALRM 终止信号 alarm()函数(定时器)
17)SIGCHLD 内核级忽略信号 子进程退出时会向父进程发送该信号
18)SIGURG 继续进程(进程切换至后台运行,通过9号信号杀掉)
19)SIGSTOP 暂停进程

可以发现,很多信号的功能(Action)是一样的,为什么这么多信号,功能却要设置一样,就定义几个信号不就行了吗?这是因为不同的信号对应不同的事件,而不同的事件处理结果可以是一样的。

五:信号捕捉

man signal

SIGNAL(2) 
#include <signal.h>
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);

首先要对void进行typedef,定义为参数为int的函数指针。 

参数一:需要捕捉的信号的编号(1-64)

参数二:对捕捉到的信号设置自定义动作

handler设置为SIG_DFL表示信号默认处理方式,SIG_ING设置为忽略处理

 

#include<signal.h>
#include<iostream>
#include<unistd.h>
typedef void (*sighandler_t)(int);
void handler(int signo)
{
    std::cout<<"进程捕捉到信号并执行自定义处理动作"<<std::endl;
}
int main()
{
    signal(2,handler);
    while(1)
    {
        std::cout<<getpid()<<std::endl;
        sleep(1);
    }
    return 0;
}

 将二号信号的动作更改为我们用户自定义的动作,而二号信号就是ctrl +c,或者kill -2,当输入ctrl+c的时候没有终止进程,而是执行我们的动作。

如果写一个循环,把每个信号都捕捉呢?那肯定不行,在Linux中,9号始终是杀死进程,19号是暂停进程。

注意:当用了signal函数后,handler并没有执行!

六:信号产生

一:终端按键产生信号 

SIGINT默认处理动作是终止进程
SIGQUIT默认处理动作是终止进程并且Core Dump

这个知识点和下篇的核心转储一起讲。

注意:ctrl+c默认动作只能杀掉前台进程

运行一个进程的时候如果+&,就会后台运行。 这里是杀不掉的,只能用kill -9

二:系统函数产生信号

2.1:kill()

man 2 kill

 

 参数1是进程pid,参数2是信号编号

成功返回0,失败返回-1

我们借用kill()来仿写一个命令行的kill命令

mykill.cc 

void usage(const std::string s)
{
    std::cout<<"\t usage: \n\t";
    std::cout<<s<<"-信号编号 进程pid"<<std::endl;
}
int main(int argc,char* argv[])
{
    if(argc != 3)
    {
        usage(argv[0]);
        exit(1);
    }
    pid_t pid = atoi(argv[2]);
    int signo = atoi(argv[1]);
    int n = kill(pid,signo);
    if(n!=0)
    {
        std::cerr<<errno<<":"<<strerror(errno)<<std::endl;
        exit(2);
    }
    return 0;
}

loop.cc

int main()
{
    while(true)
    {
        std::cout<<"我是一个进程 pid :"<<getpid()<<std::endl;
        sleep(1);
    }
    return 0;
}

argc和argv在环境变量章节有讲到(后面补),是命令行的参数个数,和命令行分割后的结果 ,需要使用c语言的atoi把命令行参数变为整形的(pid和signo)。

2.2:raise()

 参数就是信号编号

给当前进程发送信号。

成功返回0,错误返回-1

2.3:abort() 

让当前信号接收到信号而终止。因为有exit,所以abort很少用,abort函数总是会成功的所以没有返回值。 

三:软件条件产生信号

alarm是14号信号

#include <unistd.h>
unsigned int alarm(unsigned int seconds);
调用alarm函数可以设定一个闹钟,也就是告诉内核在seconds秒之后给当前进程发SIGALRM信号, 该信号的默认处理动
作是终止当前进程。

可以通过alarm,来查看一个机器的算力。如:

static int n = 0;
void myhandler(int signo)
{
    std::cout<<"n = :"<<n<<std::endl;
    exit(0);
}
int main()
{
    signal(SIGALRM,myhandler);
    alarm(1);
    while(1)
    {
        ++n;
    }
    return 0; 
}

捕捉alarm的信号改为用户自定义信号。否则默认动作退出进程不知道n是多少。

 可以看到n是4亿多。

 再看alarm函数,返回值是上一个闹钟剩下的时间,验证一下:

void myhandler(int signo)
{
    int n = alarm(10);
    std::cout<<"last remain time: "<<n<<std::endl;
}
int main()
{
    std::cout<<getpid()<<std::endl;
    signal(SIGALRM,myhandler);
    alarm(10);
    // while(1)
    // {
    //     ++n;
    // }
    while(true)
    {
        sleep(1);
    }
    return 0; 
}

 

 本节讲完,坐等下篇!

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

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

相关文章

安全测试:配置管理潜在威胁

一、配置管理威胁有哪些 明文信息传输漏洞敏感信息泄露默认或可猜解用户账户会话重放攻击测试验证码缺陷http方法测试 二、明文信息传输和存储漏洞 漏洞描述&#xff1a; 页面中没有对传输的用户名和密码等敏感信息进行加密后传输。用户密码后台存储是否加密。 产生原因&a…

MySQL安装版步骤

百度网盘有安装版、解压包安装包以及visual插件 链接&#xff1a;https://pan.baidu.com/s/1XXvWa40FYX5mtqofW_knIg 提取码&#xff1a;ky2q 下载地址https://downloads.mysql.com/archives/installer/ 双击下载好的exe文件&#xff0c;选择Custom自定义安装&#xff0c;点…

内联函数-取决于编译器

内联函数 以inline修饰的函数叫做内联函数&#xff0c;编译时C编译器会在调用内联函数的地方展开&#xff0c;没有函数调用建立栈帧的开销&#xff0c;内联函数提升程序运行的效率。 内联函数完美解决了宏函数上述所以缺点&#xff0c;但是不是所有函数都要搞成内联函数&#…

CentOS7(一)安装和基础配置

文章目录 一、CentOs 7 下载与安装二、安装过程三、安装Ohmyzsh1、基础软件安装2、编辑 install.sh4、修改仓库地址5、修改shell6、编辑主题和插件7、刷新配置8、创建用户级别配置文件 四、研发环境配置四、centos不能访问github&#xff0c;速度慢五、防火墙相关六、wget 下载…

Scala中的Map 集合详解

目录 一、不可变长Map集合 1.map的声明与遍历 2.map的常用方法&#xff1a;get、getOrElse、keys、values、、&#xff1a; 二、可变长Map集合 三、Map的其他方法 key -> value 的语法形式实际上是用库中的隐式转换实现的&#xff0c;实际调用了 Map.apply 方法。Map.a…

多维时序 | MATLAB实现BO-CNN-LSTM贝叶斯优化卷积神经网络-长短期记忆网络多变量时间序列预测

多维时序 | MATLAB实现BO-CNN-LSTM贝叶斯优化卷积神经网络-长短期记忆网络多变量时间序列预测 目录 多维时序 | MATLAB实现BO-CNN-LSTM贝叶斯优化卷积神经网络-长短期记忆网络多变量时间序列预测效果一览基本介绍模型搭建程序设计参考资料 效果一览 基本介绍 MATLAB实现BO-CNN-…

我看谁没看过

vue在新窗口打开页面方法 const { href } this.$router.resolve({path: "/officePlatform/addPrompt"});window.open(href, "_blank"); 添加圆形标志 h3::before {content: "";display: inline-block;width: 13px;height: 13px;background: va…

易点易动设备管理平台帮助化工企业实现设备高效管理

在现代化工企业中&#xff0c;设备管理和能耗监控是至关重要的。易点易动设备管理平台通过整合设备台账、巡检、维修、保养、备件管理、设备监控和能耗监控功能&#xff0c;为化工企业提供了一套全面、高效的解决方案。本文将详细介绍易点易动设备管理平台如何帮助化工企业实现…

JVM字节码分析

文章目录 1、类文件结构1.1、 魔数1.2、 版本1.3 、常量池1.4、 访问标识与继承信息1.5、 Field 信息1.6、 Method 信息1.7 、附加属性 2、字节码指令2.1、javap工具2.2、图解方法执行流程2.2.1 常量池载入运行时常量池2.2.2 方法字节码载入方法区2.2.3 main线程开始运行&#…

windows下另一种傻瓜式从零部署cuda环境的方式

前言 最近因为连续部署了两个深度学习环境&#xff0c;实在嫌烦了&#xff0c;于是摸索出一条简便的方式希望让人人都可以傻瓜式的快速部署&#xff0c;首先确保你的硬盘具有20G以上的空间&#xff0c;这里以部署torch的gpu版和让onnxruntime使用cuda加速为例&#xff0c;让我…

PDF.js源码使用总结

1、官网地址 pdf.js官网&#xff08;http://mozilla.github.io/pdf.js/&#xff09; pdf.js源码&#xff08;https://github.com/mozilla/pdf.js&#xff09; 版本选择&#xff1a;点击Tags 2、选择对应版本zip包下载、解压 在进行npm install之前 (注意&#xff1a;node.js…

【c++初阶】:引用

c入门 一.概念二.使用三.应用四.常引用五.引用与指针 一.概念 c语言中我们常用指针找地址&#xff0c;但在c中&#xff0c;忽略了指针&#xff08;当然也可以使用指针&#xff09;。常用引用这个概念。 二.使用 可以看到这里的b和c本质上都是a&#xff0c;只是不同的称呼罢了。…

【NestJs】数据库重构

上一篇文章详细了介绍nestjs 配置数据库&#xff0c;有不懂的小伙伴可以先查看上一篇文章【NestJs】使用连接mysql企业级开发规范在继续往下。 今天这一篇文章主要是针对配置数据库的重构&#xff0c;使用代码规范&#xff0c;方便后期维护。 当应用变得复杂 我们需要借用TypeO…

webstorm常用快捷键

webstorm作为前端代码JavaScript开发的利器&#xff0c;真的特别好用&#xff0c;我就总结一下我工作中经常用到的快捷键&#xff0c;有些快捷键是我自定义配置的&#xff0c;是以mac电脑来总结这篇文章的&#xff0c;请知晓&#xff1a; 自定义配置快捷键&#xff1a; 常用快…

SpringCloud源码探析(五)-网关Gateway的使用

1.概述 在微服务架构中&#xff0c;网关提供了统一的对外访问入口&#xff08;自身跨一个或多个服务&#xff09;&#xff0c;它保证了内部服务对外暴露的合理性与安全性、降低了服务之间访问的复杂性&#xff0c;是微服务架构中至关重要的一部分。在SpringCloud中网关主要包含…

让观众近距离感受如然之光 lipro智能家居成上海车展亮点之一

近段时间&#xff0c;上海国际车展如火如荼地举行&#xff0c;吸引了众多汽车厂商及相关企业参展。在本次展会上&#xff0c;星纪魅族集团也携手亿咖通科技&#xff0c;以联合参展的形式登陆「上海国际车展」 6.1号馆&#xff0c;共同展示智能汽车解决方案及产品创新。此外&…

第十四届蓝桥杯研究生组2023年省赛题解--全部采用Java语言实现

引言 今天现在这里 挖个坑&#xff0c;太忙了&#xff0c;这个专题不一样有时间补完&#xff0c;但我会尽力而为的。记录一下今天的日子&#xff1a;2023/04/21 看看这个坑要什么时候自己才能补完。 题目pdf下载&#xff1a;第十四届蓝桥杯研究生组pdf下载 在此特别感谢博主…

flac转换成mp3,4种方法教会你

怎么把flac转换成mp3&#xff1f;由于互联网技术的不断提升&#xff0c;我们每天接触到的各种音频格式变得越来越多样化。然而&#xff0c;有些特殊格式的音频会在处理时带来一定困难&#xff0c;因为它们的兼容性较差&#xff0c;不能在常用播放器上正常播放&#xff0c;这就给…

React面试题

React 如何创建一个react的项目&#xff08;使用脚手架&#xff09; 安装cr脚手架&#xff1a;npm install -g create-react-app进入文件夹&#xff1a;create-react-app 项目名称进入项目&#xff1a;cd 项目名称运行项目&#xff1a;npm start 如何不使用脚手架创建一个项…

maven打包学习

这篇文章不错&#xff1a; 思考&#xff1a;打包的时候是按照当前项目为标准打包的&#xff0c;那么所有的冲突都会以当前pom为根pom打包。那么&#xff0c;如果jar冲突&#xff0c;会用当前pom的依赖jar。 根据这个文章做了个有趣的实验&#xff1a; object3 //install 2个…