C++面试题:Linux系统信号详解
在C++面试中,理解Linux信号机制是考察系统编程能力的关键点之一。
信号(Signal)是Linux中进程间通信的异步通知机制,用于处理突发事件(如中断、异常或强制终止)。
以下是Linux系统常见信号的分类、含义及典型应用场景,基于最新POSIX标准和常见实现整理。信号分为普通信号(编号1-31)和实时信号(32-64),本文重点介绍31个普通信号。
一、信号核心概念
- 信号本质:软中断,由内核、用户或其他进程发送,通知目标进程状态变化(如终端断开、内存错误等)
- 处理方式:
- 默认动作:终止进程(Term)、生成核心转储(Core)、忽略(Ignore)、停止(Stop)或继续(Continue)
- 自定义处理:通过
signal()
或sigaction()
注册处理函数,但SIGKILL
和SIGSTOP
不可被捕获、阻塞或忽略
- 查看命令:终端执行
kill -l
可列出所有信号
二、常见Linux信号列表(精选15个关键信号)
以下是面试中最常涉及的信号,包括编号、名称、触发原因及默认动作:
编号 | 信号名称 | 触发原因 | 默认动作 |
---|---|---|---|
1 | SIGHUP | 终端挂断(如SSH断开)、守护进程重载配置(如Nginx刷新) | 终止进程 |
2 | SIGINT | 用户输入Ctrl+C 中断前台进程 | 终止进程 |
3 | SIGQUIT | 用户输入Ctrl+\ 退出进程 | 终止并生成core |
4 | SIGILL | 执行非法指令(如CPU不支持的指令) | 终止并生成core |
6 | SIGABRT | 调用abort() 函数或断言失败 | 终止并生成core |
8 | SIGFPE | 算术错误(如除零、浮点溢出) | 终止并生成core |
9 | SIGKILL | kill -9 强制终止进程(不可捕获) | 立即终止 |
11 | SIGSEGV | 非法内存访问(如空指针解引用、缓冲区溢出) | 终止并生成core |
13 | SIGPIPE | 向无读端的管道写入数据(如网络连接断开后继续写) | 终止进程 |
14 | SIGALRM | 定时器到期(由alarm() 或setitimer() 设置) | 终止进程 |
15 | SIGTERM | 默认终止信号(kill 命令不加参数时发送),允许进程清理资源 | 终止进程 |
17 | SIGCHLD | 子进程终止或停止时通知父进程 | 忽略 |
18 | SIGCONT | 恢复被暂停的进程(如fg 命令) | 继续执行 |
19 | SIGSTOP | 暂停进程(不可捕获,Ctrl+Z 触发SIGTSTP ) | 停止进程 |
20 | SIGTSTP | 终端暂停信号(Ctrl+Z ) | 停止进程 |
注:
- 生成core文件:用于调试,记录进程崩溃时的内存状态(需系统配置允许)
- 不可靠信号:编号1-31的信号可能丢失(如连续发送时),而实时信号(32+)支持排队
三、信号在C++中的处理
在C++系统编程中,需掌握信号处理函数:
- 注册信号处理:
#include <csignal>
void handler(int sig) { /* 自定义逻辑 */ }
signal(SIGINT, handler); // 捕获SIGINT
- 发送信号:
- 终端:
kill -<信号编号> <PID>
- 代码:
kill(<PID>, SIGTERM)
或raise(SIGABRT)
(向自身发送)
- 终端:
- 注意事项:
- 信号处理函数应避免复杂操作(如调用非异步安全函数),否则可能引发重入问题。
- 多线程中信号处理需谨慎,建议使用
pthread_sigmask
屏蔽信号
四、面试常见问题扩展
-
SIGKILL
vsSIGTERM
:SIGTERM
允许进程优雅退出(可自定义清理);SIGKILL
强制终止(内核直接回收资源)
- 信号屏蔽:
- 使用
sigprocmask
阻塞信号(如防止SIGINT
中断关键代码),sigpending
检查未决信号
- 使用
- 实际应用场景:
- 服务器:
SIGHUP
重载配置,SIGCHLD
回收子进程资源。 - 调试:
SIGSEGV
定位内存错误,SIGTRAP
(5)配合断点调试
- 服务器:
【C语言】零基础到项目实战
【C语言/C++】零基础到项目实战
初学者营地:1021486511