linux怎么接收信号
linux怎么接收信号详细介绍
在 Linux 中,程序接收信号通常通过 注册信号处理函数 实现,可使用 signal 或 sigaction 函数。以下是详细步骤和示例:
一、信号处理基础
信号是 Linux 系统中进程间通信(IPC)的一种机制,每个信号对应一个编号(如 SIGINT 对应 2,代表键盘中断)。程序可通过以下方式处理信号:
- 默认处理:使用系统预设行为(如终止进程、忽略信号等)。
- 自定义处理:注册函数自定义信号响应逻辑。
- 忽略信号:对特定信号不做处理。
二、使用
signal 函数(简单方式)
1. 函数原型
c
signum handler
signum:信号编号(如SIGINT、SIGTERM)。handler:处理函数(参数为信号编号),或使用SIG_IGN(忽略)、SIG_DFL(默认处理)。
2. 示例:处理
SIGINT 信号(Ctrl+C)
c
sig
sig
SIGINT handle_int
- 编译运行:
gcc signal_demo.c -o signal_demo && ./signal_demo - 按下
Ctrl+C时,会触发handle_int函数,而非默认的终止进程。
三、使用
sigaction 函数(推荐,更灵活)
sigaction 可设置信号处理的更多细节(如信号掩码、标志位),兼容性和可靠性更好。
1. 函数原型
c
signum act oldact
act:指向新处理方式的结构体,包含处理函数、标志位、信号掩码等。oldact:存储旧处理方式(可选,可设为NULL)。
2.
struct sigaction 结构体
c
sa_handler
sa_sigaction
sa_mask
sa_flags
3. 示例:处理
SIGTERM 信号并阻塞其他信号
c
sig
sig
act
actsa_handler handle_term
actsa_mask
actsa_flags
SIGTERM act
四、特殊处理方式
- 忽略信号:
cSIGINT SIG_IGN - 恢复默认处理:
cSIGINT SIG_DFL
五、命令行发送信号(配合测试)
通过 kill 命令向进程发送信号:
bash
./signal_demo
六、注意事项
- 不可捕获 / 忽略的信号:
SIGKILL(9)和SIGSTOP(19)无法被程序捕获或忽略,只能由系统使用。
- 信号处理函数的限制:
- 处理函数应保持简单,避免调用非异步安全的函数(如
printf是安全的,但malloc等可能不安全)。 - 建议通过设置标志位,让主程序处理复杂逻辑,避免在信号处理函数中执行耗时操作。
- 处理函数应保持简单,避免调用非异步安全的函数(如
- 多线程场景:
- 信号默认由进程接收,线程间信号处理需通过
pthread_sigmask等函数管理。
- 信号默认由进程接收,线程间信号处理需通过
通过上述方法,程序可自定义信号响应逻辑,实现优雅的中断处理、资源释放等功能。推荐优先使用 sigaction 以获得更可靠的行为。