Linux周期性信号生成示例
写一个linux下不断产生信号的demo
以下是一个在Linux下周期性地产生信号的示例程序。该程序每秒触发一次SIGALRM信号,并在信号处理函数中重置定时器以实现持续触发:
1 |
|
说明:
- 信号选择:使用
SIGALRM定时器信号,通过alarm函数设置定时触发。 - 信号处理:
- 在
handler函数中调用alarm(1)实现定时器循环。 - 使用
write而非printf,避免信号处理中调用不可重入函数。
- 在
- 安全性:
- 使用
sigaction注册信号处理函数(比signal更可靠)。 - 通过
sigemptyset清空阻塞信号集,确保处理函数执行时不阻塞其他信号。
- 使用
编译运行:
- 保存为
signal_demo.c。 - 终端执行:
1
2gcc signal_demo.c -o signal_demo
./signal_demo - 程序每秒输出一次
Signal received,按Ctrl+C终止。
扩展:
- 修改
alarm(1)中的数值调整触发间隔(单位:秒)。 - 替换
SIGALRM为其他信号(如SIGUSR1),需配合kill(getpid(), SIGUSR1)在处理函数中手动触发。
Linux下发送信号
在 Linux 系统中,发送信号是进程间通信(IPC)的重要方式。以下是发送信号的常见方法(命令行工具 + 编程实现),以及对应的原理和示例:
一、命令行发送信号
1. kill 命令
语法:
1 | kill -<SIGNAL> <PID> # 向指定进程发送信号 |
示例:
1 | kill -SIGTERM 1234 # 向 PID=1234 的进程发送终止信号(默认信号为 SIGTERM) |
2. pkill / killall 命令
1 | pkill -<SIGNAL> <进程名> # 按进程名发送信号(支持正则) |
示例:
1 | pkill -SIGUSR1 chrome # 向所有 chrome 进程发送自定义信号 |
二、编程发送信号(C语言)
1. kill() 函数
原型:
1 |
|
参数:
pid > 0:目标进程的 PIDpid == 0:发送给当前进程组的所有进程pid == -1:广播信号(需要权限)pid < -1:发送给进程组 ID 为|pid|的进程组
示例:
1 |
|
2. raise() 函数
向当前进程自身发送信号:
1 |
|
三、其他工具发送信号
1. Python 脚本
1 | import os |
2. 键盘组合键
Ctrl + C→ 发送 SIGINT(终止进程)Ctrl + \→ 发送 SIGQUIT(终止并生成 core dump)Ctrl + Z→ 发送 SIGTSTP(挂起进程)
四、常见信号列表
| 信号名 | 值 | 默认行为 | 用途 |
|---|---|---|---|
| SIGHUP | 1 | 终止 | 终端挂断/重新加载配置 |
| SIGINT | 2 | 终止 | 键盘中断(Ctrl+C) |
| SIGQUIT | 3 | 终止 + core dump | 键盘退出(Ctrl+\) |
| SIGKILL | 9 | 终止 | 强制杀死进程(不可捕获) |
| SIGTERM | 15 | 终止 | 优雅终止进程(默认信号) |
| SIGUSR1 | 10 | 终止 | 用户自定义信号 |
| SIGUSR2 | 12 | 终止 | 用户自定义信号 |
五、注意事项
权限限制:
- 普通用户只能向自己的进程发送信号。
SIGKILL和SIGSTOP不能被捕获、阻塞或忽略。
PID 有效性:
- 确保目标 PID 存在,否则
kill()会返回错误(ESRCH)。
- 确保目标 PID 存在,否则
竞态条件:
- 在多进程编程中,发送信号前应检查目标进程是否存活。
通过上述方法,您可以灵活控制进程行为,如优雅终止服务(SIGTERM)、强制杀死卡死进程(SIGKILL),或通过自定义信号(SIGUSR1/SIGUSR2)实现进程间协作。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Helloeuler!
