什么是信号,谁会向进程发送信号?进程收到信号后,进程会如何处理(信号)【linux】(zp)

什么是信号

信号是一种通知进程某件事情发生了的一种通信机制,通过向进程发送某个信号,可以告诉进程发生了什么事情,进程收到这个信号后,
就知道某事情发生了,进程可以做出相应的响应(处理),所以其实信号也是一种通信机制,目的就是用于告诉进程发生了什么事情。

不过Linux所实现的信号这种通信机制,与我们后面的IPC(进程间通信)博客所不同的是,信号属于不精确通信,信号只能告诉进程大概发生了什么事情,但是不能准确的告诉进程详细的细节信息。

这就好比以前长城放狼烟是一样的,放狼烟就是一种信号,只能告诉你敌人来了,大概来了多少人,但是无法告诉更多更详细的情报,
但是如果是电话、电报的话,就属于精确通信,不仅可以告诉你敌人来了,还会告诉你敌军的详细情况。

并不是有了精确的IPC后,就可以将信号淘汰,信号有自己应用场合。

学习信号的意义

开发的需要
比如ctrl+c为什么可以结束进程?
产生指针错误时为什么进程能够自动结束,并提示产生了“segment fault”(段错误)?
kill命令到底是怎么结束进程的?
等一系列问题。

有利于知识的横向对比和理解
c、c++、java的线程库有类似的信号概念,QT界面开发时有类似信号和槽的概念,如果你对系列博客说明的Linux的信号机制有所理解的,你会发现其实所有的信号机制的实现,原理都是相通的。

信号

信号是一种向进程发送通知,告诉其某件事情发生了的一种简单通信机制。

信号的命名

Linux下边定义了很多的信号,所有的信号都是一个整数编号,不过为了好辨识,Linux系统给这些整数编号都定义了对应的宏名,宏名都是以SIG开头,比如SIGABRT。

SIG:signal的缩写
ABRT:abort的缩写

宏名SIG***,***是对信号的描述,ABRT表示放弃的意思,向进程发送SIGABRT信号,进程会被信号异常终止。
在前面的博客我们就使用过,当我们调用abort函数时,该函数就会向进程发送一个SIGABRT信号,看到ABRT就知道与abort函数有关系。

谁会向进程发送信号?

在这里插入图片描述

总结起来,会有三个“人”会向进程发送信号,分别是“另一进程”、“OS内核”、“硬件”。

另一个进程发送信号

比如在命令行终端窗口通过kill命令向某个进程发送一个信号将其终止。

演示:
我们让一个进程进入死循环:

#include <stdio.h>
int main()
{
        printf("this is hello\n");
        while(1);
}

运行结果为:
在这里插入图片描述

通过ps -a找到hello进程的PID进行kill操作
在这里插入图片描述

hello接收到kill信号之后终止,就会从进程列表消失:

在这里插入图片描述

内核发送信号

发生了某个事件,Linux内核可能会发送该事件对应的信号给某个进程
进程从管道文件读取数据,但是管道文件的读权限被关闭了,进程会被内核发送一个SIGPIPE信号,提示读管道出错了。后面在进程间通信的博客中,会说明这个问题。

如果操作某个地址,但是地址只允许读不想允许写,但是如果非要写数据就会写失败,内核就会向当前尝试写操作的进程发送一个SIGSEGV信号,进程就会直到,对于地址的操作失败了。

底层硬件发送信号

底层硬件发生了某个事件,会向进程发送对应的某个信号

比如按下ctrl+c按键终止进程时,内核收到ctrl+c按键后,会向正在运行的进程发送SIGINT信号,将其异常终止。

不管进程是被哪一个信号给终止了,
只要是被信号终止的,都是异常终止

进程收到信号后,进程会如何处理

三种处理方式,分别是忽略、捕获、默认。

忽略

忽略的意思就是说,进程就当信号从来没有发生过。
这就好比别人送了封信给你,但是你忽略这封信的存在,那么这封信将不会对你产生任何影响。

捕获

捕获的意思就是说,进程会调用相应的处理函数,进行相应的处理。

默认

如果不忽略也不捕获的话,此时进程会使用系统设置的默认处理方式来处理信号。

发布了163 篇原创文章 · 获赞 94 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_43648751/article/details/104601239