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!