Linux信号处理机制
Linux信号处理机制
什么是信号
信号是Linux系统中进程间通信的一种异步方式。信号可以中断进程的正常执行流程。
常见信号
| 信号 | 编号 | 说明 | 默认动作 |
|---|---|---|---|
| SIGHUP | 1 | 挂起 | 终止 |
| SIGINT | 2 | 中断(Ctrl+C) | 终止 |
| SIGQUIT | 3 | 退出(Ctrl+\) | 终止+core |
| SIGKILL | 9 | 强制终止 | 终止 |
| SIGTERM | 15 | 正常终止 | 终止 |
| SIGSTOP | 19 | 暂停 | 暂停 |
| SIGCONT | 18 | 继续 | 继续 |
| SIGUSR1 | 10 | 用户自定义1 | 终止 |
| SIGUSR2 | 12 | 用户自定义2 | 终止 |
发送信号
# 使用kill命令
kill PID # 发送SIGTERM
kill -9 PID # 发送SIGKILL
kill -HUP PID # 发送SIGHUP
kill -USR1 PID # 发送SIGUSR1
# 使用pkill
pkill -HUP nginx # 按名称发送
pkill -u username # 按用户发送
捕获信号
Shell脚本中
#!/bin/bash
# 捕获SIGINT
trap 'echo "收到中断信号"; exit' INT
# 捕获SIGTERM
trap 'echo "收到终止信号"; cleanup; exit' TERM
# 忽略信号
trap '' INT
# 恢复默认处理
trap - INT
# 清理函数
cleanup() {
echo "执行清理操作"
rm -f /tmp/lockfile
}
while true; do
echo "运行中..."
sleep 1
done
C语言中
#include <signal.h>
#include <stdio.h>
void handler(int sig) {
printf("收到信号: %d\n", sig);
}
int main() {
signal(SIGINT, handler);
signal(SIGTERM, handler);
while(1) {
sleep(1);
}
return 0;
}
信号与服务管理
# 重载Nginx配置
kill -HUP $(cat /var/run/nginx.pid)
# 或
nginx -s reload
# 重新打开日志文件
kill -USR1 $(cat /var/run/nginx.pid)
# 平滑重启
kill -USR2 $(cat /var/run/nginx.pid)
信号掩码
# 查看信号掩码
cat /proc/self/status | grep SigBlk
# 屏蔽信号
trap '' TERM # 在Shell中
sigprocmask() # 在C中
实践:进程优雅退出
#!/bin/bash
PID=$$
LOCKFILE="/tmp/myapp.pid"
# 写入PID
echo $PID > $LOCKFILE
# 清理函数
cleanup() {
echo "正在停止服务..."
rm -f $LOCKFILE
exit 0
}
# 捕获信号
trap cleanup SIGTERM SIGINT SIGHUP
echo "服务已启动,PID: $PID"
# 模拟服务运行
while true; do
sleep 1
done
信号与Cron
# Cron作业被中断时发送SIGHUP
# 可以在脚本中捕获
trap 'exit' HUP
总结
信号是Linux进程控制的重要机制。理解信号的使用场景和处理方式,能够编写更加健壮的系统程序。