Linux基础 (十):Linux 信号的使用

目录

一、信号的基本概念

二、信号处理常见方式概览

三、修改信号的响应方式 – signal()

3.1 简单复习结束前台进程

3.2  改变SIGINT信号的响应方式

3.3 自定义方式改变进程对信号的响应

3.4 进程对信号作出两种响应

四、发送信号 – kill()

五、利用信号解决僵死进程问题


一、信号的基本概念

       Linux 信号(signals)是一种用于进程间通信(Inter-Process Communication,IPC)的机制,允许进程通过发送和接收信号来通知其他进程某些事件的发生。信号是中断处理的一种手段,可以打断一个进程的正常执行流,迫使它处理特定的事件。与信号有关的系统调用在“signal.h”头文件中有声明 。信号是进程之间事件异步通知的一种方式,属于软中断。每个信号都有一个编号和一个宏定义名称,这些宏定义可以在signal.h中找到,例如其中有定 义 #define SIGINT 2

常用信号

在Linux中,有几种常用的信号:

  • SIGHUP (1): 挂起信号,通常用于重新加载配置文件或重启服务。
  • SIGINT (2): 中断信号,通常由Ctrl+C生成,用于中断进程。
  • SIGQUIT (3): 退出信号,由Ctrl+\生成,用于退出进程并生成核心转储文件。
  • SIGILL (4): 非法指令信号,通常由非法指令生成。
  • SIGABRT (6): 异常终止信号,通常由abort函数生成。
  • SIGFPE (8): 浮点异常信号,通常由除零或其他浮点操作错误生成。
  • SIGKILL (9): 终止信号,不能被忽略或捕获,用于强制终止进程。
  • SIGSEGV (11): 段错误信号,通常由非法内存访问生成。
  • SIGPIPE (13): 管道破裂信号,通常在向一个没有读端的管道写数据时生成。
  • SIGALRM (14): 定时器信号,通常由alarm函数生成。
  • SIGTERM (15): 终止信号,用于正常终止进程。
  • SIGUSR1 (10) 和 SIGUSR2 (12): 用户自定义信号。
  • SIGCHLD (17 )子进程结束后,会默认给父进程发送该信号

二、信号处理常见方式概览

        一个进程对于信号的响应方式可选的处理动作有以下三种:

  1. 忽略此信号。
  2. 执行该信号的默认处理动作。
  3. 提供一个信号处理函数,要求内核在处理该信号时切换到用户态执行这个处理函数,这种方式称为捕捉 (Catch)一个信号。

signal()的两个参数 第一个是信号代号,第二个是一个函数(参数为int类型,返回值为void)  

三、修改信号的响应方式 – signal()

3.1 简单复习结束前台进程

         用户输入命令,. 用户按下Ctrl-C ,这个键盘输入产生一个硬件中断,被操作系统获取,解释成信号,发送给目标前台进程 .,前台进程因为收到信号,进而引起进程退出。

注意

  1. Ctrl-C 产生的信号只能发给前台进程。一个命令后面加个&可以放到后台运行,这样Shell不必等待进程 结束就可以接受新的命令,启动新的进程。
  2. Shell可以同时运行一个前台进程和任意多个后台进程,只有前台进程才能接到像 Ctrl-C 这种控制键产生的信号。
  3. 前台进程在运行过程中用户随时可能按下 Ctrl-C 而产生一个信号,也就是说该进程的用户空间代码执行到任何地方都有可能收到 SIGINT 信号而终止,所以信号相对于进程的控制流程来说是异步 (Asynchronous)的。

3.2  改变SIGINT信号的响应方式

       SIGINT (2): 中断信号,通常由Ctrl+C生成,用于中断进程,用户按下Ctrl-C ,这个键盘输入产生一个硬件中断,被操作系统获取,解释成信号,发送给目标前台进程 .,前台进程因为收到信号,进而引起进程退出。这里我们利用signal()系统调用改变它的响应方式为忽略。

3.3 自定义方式改变进程对信号的响应

3.4 进程对信号作出两种响应

四、发送信号 – kill()

kill() 可以向指定的进程发送指定的信号:

五、利用信号解决僵死进程问题

         进程复制与替换一章讲过用wait函数清理僵尸进程,父进程可以阻塞等待子进程结束,也可以非阻塞地查询是否有子进程结束等待清理(也就是轮询的方式)。采用第一种方式,父进程阻塞了就不 能处理自己的工作了;采用第二种方式,父进程在处理自己的工作的同时还要记得时不时地轮询一下,程序实现复杂。 其实,子进程在终止时会给父进程发SIGCHLD信号,该信号的默认处理动作是忽略,父进程可以自定义SIGCHLD信号 的处理函数,这样父进程只需专心处理自己的工作,不必关心子进程了,子进程终止时会通知父进程,父进程在信号处理函数中调用wait清理子进程即可

请编写一个程序完成以下功能:父进程fork出子进程,子进程调用exit(0)终止,父进程自定义SIGCHLD信号的处理函数, 在其中调用wait获得子进程的退出状态并打印。 事实上,由于UNIX 的历史原因,要想不产生僵尸进程还有另外一种办法:父进程调 用signal将SIGCHLD的处理动作置为SIG_IGN,这样fork出来的子进程在终止时会自动清理掉,不会产生僵尸进程,也不会通知父进程。系统默认的忽略动作和用户用signal函数自定义的忽略通常是没有区别的,但这是一个特例。此方法对于Linux可用,但不保证 在其它UNIX系统上都可用。

以上就是全部内容!请务必掌握,这是后续学习的基础,欢迎大家点赞加关注评论,您的支持是我前进最大的动力!下期再见!

  • 20
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

未来可期,静待花开~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值