【进程通信】Signal信号
信号(signal)
软中断信号(signal,又简称为信号)是Linux下用来在进程间传递消息的方式之一,也是进程间唯一的异步通信方式。从命名中可以看出信号的实质很像中断。进程间可以通过调用kill库函数发送软中断信号,Linux内核也可能给进程发送信号,用以告知该进程发生了某个异步事件。
注意,信号只用来告知进程发生了某个异步事件,并不用来传递数据。进程收到信号后会有三种处理方式:
- 忽略,不做任何处理
- 执行预先设置的处理函数(就像中断服务程序一样)
- 采用系统的默认操作,大部分是终止进程
信号的来源
用户
一般是键盘的输入会作为信号发送给进程,比如:
Ctrl + C
发送SIGINT信号给进程,默认动作为终止进程;Ctrl + \
发送SIGQUIT信号给进程,默认动作为终止进程并进行内核映像转储(core dump)内核
当进程执行出错时,内核给进程发送一个对应信号,例如:非法内存引用、浮点数溢出、执行非法指令
进程
C++的kill库函数用于进程间发送信号
信号的类型
信号名 | 信号值 | 默认处理动作 | 发出信号的原因 |
---|---|---|---|
SIGINT | 2 | 终止进程 | 键盘中断Ctrl+c |
SIGQUIT | 3 | 终止进程并进行内核映像转储 | 键盘的退出键被按下 |
SIGKILL | 9 | 终止进程,并且不能被捕获、忽略 | 采用kill -9 进程编号 强制杀死程序。 |
SIGSEGV | 11 | 终止进程并进行内核映像转储 | 无效的内存引用 |
SIGTERM | 15 | 终止进程 | 采用“kill 进程编号”或“killall 程序名”通知程序。 |
SIGCHLD | 20,17,18 | 忽略此信号 | 子进程结束信号 |
PS:
内核映像转储(core dump),内核映像转储是指将进程数据在内存的映像和进程在内核结构中的部分内容以一定格式转储到文件系统,并且进程退出执行,这样做的好处是为程序员 提供了方便,使得他们可以得到进程当时执行时的数据值,允许他们确定转储的原因,并且可以调试他们的程序。
信号的捕获处理
#include <signal.h>
sighandler_t signal(int signum, sighandler_t handler)
//signum 表示信号的编号//handler 表示信号的处理方式,有三种:1. SIG_IGN:忽略改信号,不作为2. SIG_DFL:恢复该信号的默认处理方法3. 自定义处理函数,注意函数参数为 (int signum)
信号的发送
int kill(pid_t pid, int sig)
//pid 目标进程号,有三种情况:1. pid>0 将信号sig传给号为pid的进程2. pid=0 将信号sig传给同进程组的所有进程(包括自己),常用于父进程给子进程发送信号3. pid=-1 将信号广播到系统内所有进程,例如系统关机时向所有登录窗口广播关机信息//sig 被发送的信号编号
信号的应用
屏蔽信号
通常为了程序不被干扰,程序开头通常会屏蔽所有信号,然后再用signal函数对关心的信号设置相应的处理方式。
for(int i=0; i<100; i++) signal(i, SIG_IGN);
搞点好玩的
改变信号 SIGINT
和 SIGTERM
的捕获处理,设计一个 ctrl+C
和 kill
都杀不掉的进程:
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>void func(int sig)
{if (sig == SIGINT)printf("\b\b杀不死,哈哈哈哈。\n");else if (sig == SIGTERM)printf("还是杀不死,哈哈哈哈。\n");
}int main()
{for (int ii = 0; ii < 100; ii++)signal(ii, SIG_IGN); // 屏蔽全部的信号signal(SIGINT, func);signal(SIGTERM, func); // 设置SIGINT和SIGTERM的处理函数while (1);
}
效果:
使用Ctrl+C
尝试关掉进程:
用 ps -ef | grep signal
找到其进程号,尝试用 kill 直接干掉:
可以看见,kill + 进程号
或 killall + 进程名
对它都无效,那改怎么杀死这个进程呢?如图,用 kill -9 进程号
:
因为kill -9 进程号
发送的信号是 SIGKILL,这个信号无法被捕获或忽略,能够快准狠杀掉进程
使系统休眠
这个是我尝试用 kill() 函数向系统所有进程发送 SIGKILL 信号后发现的,当然是在虚拟机上,我可不敢在主机上这样搞:
#include <stdio.h>
#include <signal.h>int main()
{kill(-1, SIGKILL);
}
效果是虚拟机进入休眠,输入密码后能再进入,原以为会直接关机呢
【进程通信】Signal信号相关推荐
- 【通信】网络通信 进程通信 同步异步通信
通信 网络通信 三次握手 四次挥手 为什么TCP连接需要三次握手,两次不可以吗?为什么? TCP连接的特点 TCP流量控制-滑动窗口 TCP拥塞控制 TCP与UDP的区别 进程和线程的区别 进程间通信 ...
- 【信号】信号处理与进程通信:快速上手
目录 0. 信号概述 1. 产生信号的方式: 1.1 当用户按某些终端键时,将产生信号. 1.2 硬件异常将产生信号. 1.3 软件异常将产生信号. 1.4 调用kill函数将发送信号. 1.5 运行 ...
- Liunx系统编程篇—进程通信(五)信号
Liunx系统编程篇-进程通信(五)信号 原理 对于Linux,信号是软中断,例如下课铃响了,老师要停止讲课.许多重要的程序都需要处理信号. 信号,为 Linux 提供了一种处理异步事件的方法.比如, ...
- 【进程】进程通信-信号方式(中断)
信号方式(中断) 信号的基本概念 每个信号都对应一个正整数常量(称为signal number,即信号编号.定义在系统头文件<signal.h>中),代表同一用户的诸进程之间传送事先约定 ...
- Linux--信号signal、父子进程、SIGCHLD信号相关命令
目录 1.概念: 2.信号的存储位置: 3.常见的信号的值以及对应的功能说明: 4.信号的值在系统源码中的定义: 5.响应方式: 6.改变信号的相应方式: (1)设置信号的响应方式: (2)默认:SI ...
- Linux下进程通信知识点学习笔记(一)
4种主要事件导致进程创建: 系统的初始化: 执行了正在运行的进程所调用的进程创建系统调用: 用户请求创建一个进程: 一个批处理作业的初始化: 进程的终止: 正常退出: 出错退: 严重错误: 被其他进程 ...
- linux进程间通讯-信号
文章目录 进程间通信功能 信号 信号的概念 产生信号的方式 信号的默认(缺省)处理方式 进程接收到信号后的处理方式 kill函数 alarm函数 raise函数 abort函数 pause函数 sig ...
- linux一个进程通知另外一个进程,Linux进程通信学习笔记
一.为什么需要进程通信 1)数据传输 一个进程需要把它的数据发送给另一个进程. 2)资源共享 多个进程之间共享同样的资源. 3)通知事件 一个进程向另外一个进程发送消息,通知它发生了某事件. 4)进程 ...
- NGINX 进程通信机制
nginx的进程通信分为三种类别:linux 系统与nginx 通信, master 进程与worker进程通信, worker进程间通信. master进程管理worker进程,本文将追溯nginx ...
最新文章
- 【组队学习】【34期】Python(一级)
- 【牛客每日一题】4.15 Treepath 题解(树上dfs/树形DP)
- 【PySlowFast】Facebook开源算法代码库PySlowFast,轻松复现前沿视频理解模型
- 母亲,我怎么让妳等了那么久...
- JS 正则匹配字符串
- 如何用纯 CSS 创作一个方块旋转动画
- MySQL-基本的SELECT语句
- 从CSRF原理到CMS漏洞利用
- Python环境 及安装
- linux文件分别打包命令,Linux文件打包命令
- bash 的相关配置
- 求一列数据中的波峰_pandas查看缺失数据占比(实战)
- 学模具设计应该掌握哪些内容?
- 斐讯t1刷入linux系统,斐讯phicomm n1刷入Gentoo系统斐讯N1刷Linux系统教程
- java win10窗口启动假死_win10系统下桌面经常假死如何解决
- excel表格怎么换行?3个方法,你一定不知道第3个
- 小鸟云服务器上线了新的操作系统
- Java POI实现pptpptx转换为pdf文件
- 雅诗兰黛公司选出董事会新成员
- 数据基础---《利用Python进行数据分析·第2版》第12章 pandas高级应用