关于信号Signal
本文最后更新于56 天前,其中的信息可能已经过时,如有错误请发送邮件到2156936367@qq.com

信号的本质

信号是Linux系统中用于进程间通信(IPC)的一种机制,本质上是一种软件中断。它模拟了硬件中断的机制,通知进程发生了某个事件。

还是拿 “取快递”这件事来举例吧

  1. 信号识别(内置能力)
    • 快递员打电话过来,你不需要别人教你怎么接电话,这是你的本能
    • 内核在创建进程(fork)时,PCB(进程控制块)中就已经有了一张映射表,规定了数字 2 代表 SIGINT,数字 9 代表 SIGKILL 等。
  2. 信号产生
    • 可以是快递员打电话过来,也可以是手机的快递短信…….
    • 硬件层面就是键盘CTRL+C,软件层面就是kill命令…..
  3. 信号保存(重点)
    • 当快递员打电话过来的时候,你开了把GO,1v5残局,抽不开时间接电话,等打完再去取快递
    • 信号不是发给进程就立刻执行的,而是先保存在进程的 PCB 中。
      • 未决信号集(Pending):收到了信号,但还没处理。
      • 阻塞信号集(Blocked/Mask):进程告诉内核“我现在不方便处理这个信号,先留着别打断我”。
        • 注意:阻塞不等于忽略。阻塞是“延后处理”,忽略是“直接丢弃”。
  4. 信号处理时机
    • 打完了,就去取快递
    • 进程从内核态切换回用户态的前一刻。

信号的三种处理方式

  1. 默认动作(Default)
    • 大多数信号(如 SIGINT)的默认动作是终止进程
    • 部分是忽略(如 SIGCHLD)。
    • 部分是生成 Core Dump(核心转储,如 SIGSEGV 段错误),用于事后调试。
  2. 忽略(Ignore)
    • 明确告诉内核:“这个信号来了直接丢掉,别烦我”。
    • 死穴:SIGKILL (9) 和 SIGSTOP (19) 不能被忽略,这是上帝视角(管理员)的最后手段。
  3. 捕捉/自定义(Capture/Handler)
    • 写一个函数,通过 signal() 或 sigaction() 注册给内核。信号来了,暂停主程序,跑去执行这个函数。
    • 就是修改PCB里面的那张映射表,添加一个信号和对应处理动作

常见信号表

信号编号名称常用场景/含义默认动作面试考点/备注
2SIGINTCtrl + C终止友好的终止,进程可以捕获它做清理工作(如保存文件)。
3SIGQUITCtrl + \Core Dump比 Ctrl+C 狠一点,终止并生成 Core 文件供调试。
9SIGKILLkill -9强制终止不可捕捉、不可忽略、不可阻塞。立即杀死,进程无法做清理工作(可能导致数据丢失)。
11SIGSEGV非法内存访问Core Dump指针越界、野指针、访问空指针时产生。
15SIGTERMkill终止默认的 kill 信号。程序可以捕获它,优雅地退出(释放资源后自杀)。
17SIGCHLD子进程状态改变忽略子进程结束时发给父进程。父进程若不处理(调用 wait),子进程会变成僵尸进程
19SIGSTOPkill -19暂停不可捕捉、不可忽略。类似把程序“冻结”。
20SIGTSTPCtrl + Z暂停这种暂停是可以被进程捕获处理的。

补充

  1. 为什么 SIGKILL (9) 和 SIGSTOP (19) 无法被捕获?
  • 这是操作系统设计者留给系统管理员(Root)的“后门”或“尚方宝剑”。如果所有信号都能被进程捕获并忽略,写一个死循环病毒并忽略所有信号,那管理员就无法杀掉这个失控的进程,系统只能重启。
  1. kill 命令是杀进程吗?
  • kill 命令的本质是向进程发送信号
  • kill <pid> 默认发送 15号信号 (SIGTERM),告诉进程“请你自己结束”。
  • kill -9 <pid> 发送 9号信号 (SIGKILL),是内核直接动手杀人,不给进程喘息机会。

CTRL+C 发生了什么

按下 Ctrl+C,本质是硬件中断触发操作系统将输入转换为 SIGINT 信号,并发送给前台进程,最终导致进程终止的过程。

以下是详细过程:

1. 硬件输入(敲键盘) 当你按下 Ctrl + C,键盘给 CPU 发送了一个硬件中断,告诉 CPU:“有按键输入了,快来看!”

2. 系统解析(翻译) 操作系统的终端驱动程序拿到了这个输入,发现是 Ctrl + C 组合键。 系统知道这个组合键不是普通的字符,而是中断命令。于是,它把这个命令“翻译”成了一个信号:2号信号 SIGINT

3. 信号发送(找目标) 操作系统把 SIGINT 信号发送给当前终端的前台进程(就是你屏幕上正在运行的那个程序)。

4. 进程处理(执行) 进程收到了 SIGINT 信号:

  • 默认情况:直接终止运行(挂掉)。
  • 自定义情况:如果你代码里写了捕获函数(Handler),就执行你的函数(比如清理垃圾、保存进度后再退出)。

kill -USR1和kill -USR2

在操作系统内核层面,SIGUSR1 和 SIGUSR2 没有任何区别,操作系统对它们的默认处理方式都是直接终止进程 它们都是用户自定义信号(User-defined Signal),它们的区别完全取决于程序员在写代码时,给这两个信号绑定了什么功能

觉得有帮助可以投喂下博主哦~感谢!
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇