当前位置: 首页> 科技> 名企 > 企业产品网络推广_海珠区疫情防控指挥部_免费的网络推广有哪些_免费关键词搜索引擎工具

企业产品网络推广_海珠区疫情防控指挥部_免费的网络推广有哪些_免费关键词搜索引擎工具

时间:2025/7/9 11:58:10来源:https://blog.csdn.net/2301_80067496/article/details/147001393 浏览次数:1次
企业产品网络推广_海珠区疫情防控指挥部_免费的网络推广有哪些_免费关键词搜索引擎工具

Linux信号处理全解析:从入门到实战

一、初识Linux信号:系统级的"紧急电话"

  1. 信号是什么?
    信号是Linux系统中进程间通信的"紧急通知",如同现实中的交通信号灯。当用户按下Ctrl+C(产生SIGINT信号)时,相当于给程序发送了"立即停车"的指令。

  2. 常见信号速查表(精简版)
    | 信号编号 | 名称 | 触发方式 | 默认行为 |
    |----------|-----------|------------------------|------------------------|
    | 1 | SIGHUP | 终端断开 | 终止进程 |
    | 2 | SIGINT | Ctrl+C | 终止进程 |
    | 9 | SIGKILL | kill -9 | 强制终止 |
    | 15 | SIGTERM | 默认终止信号 | 优雅终止 |
    | 17 | SIGCHLD | 子进程状态改变 | 通知父进程 |

生活案例:SIGTERM(15)如同礼貌的停车请求,SIGKILL(9)则是拖车强制拖走。


二、信号操作入门:从命令行到代码

  1. 终端操作双雄:kill vs killall
优雅终止nginx进程(发送SIGTERM)
$ kill 1234 强制终止所有python进程 
$ killall -9 python 查看信号列表 
$ kill -l 

对比项:

  • kill:精确打击(需知道PID)
  • killall:范围清除(按进程名称)
  1. 编程基础:发送信号的两种姿势
// 发送信号给其他进程 
kill(pid, SIGTERM);// 给自己发送信号 
raise(SIGINT);

实验场景:创建父子进程,通过SIGCHLD实现僵尸进程回收(代码示例见附录A)


三、信号处理进阶:从接收到响应

  1. 信号处理三剑客
// 简单注册(传统方式)
signal(SIGINT, handler);// 高级注册(推荐方式)
struct sigaction sa;
sa.sa_handler = handler;
sigaction(SIGINT, &sa, NULL);

对比实验:

  • 连续快速按Ctrl+C时,signal可能丢失信号,而sigaction能正确捕获
  1. 定时器实战:闹钟与秒表
alarm(5);  // 5秒后触发SIGALRM 
ualarm(500000, 1000000); // 0.5秒后首次触发,之后每1秒触发 // 高精度定时器 
struct itimerval timer = {{2, 500000},  // 每2.5秒重复 {1, 0}        // 首次1秒后触发 
};
setitimer(ITIMER_REAL, &timer, NULL);

应用场景:实现精准心跳检测(误差<1ms)


四、信号控制艺术:精确管理的秘诀

  1. 信号集操作四部曲
sigset_t set;
sigemptyset(&set);          // 初始化空集合 
sigaddset(&set, SIGINT);    // 添加SIGINT 
sigprocmask(SIG_BLOCK, &set, NULL); // 阻塞信号 
sigpending(&set);           // 查看待处理信号 
  1. 信号屏蔽的三种策略
    | 策略 | 效果 | 适用场景 |
    |--------------|--------------------------------|------------------------|
    | 完全阻塞 | 信号永不递送 | 关键代码段保护 |
    | 临时阻塞 | 延迟信号处理 | 事务操作 |
    | 选择性接收 | 通过sigsuspend控制 | 高并发事件处理 |

五、sigsuspend的原子魔法:解决世纪难题

  1. 传统方案的致命缺陷
sigprocmask(SIG_UNBLOCK, &set, NULL); // 解除阻塞 
pause(); // 这里可能永远阻塞!
  1. sigsuspend的原子化操作
sigset_t mask;
sigfillset(&mask);
sigsuspend(&mask); // 原子化:解除阻塞+等待信号 

原理图解:

[初始状态] -> [保存掩码] -> [设置新掩码] -> [等待信号]↑                                  |+--------[恢复原始掩码]←-----------+
  1. 实战案例:安全信号等待器
void handler(int sig) {printf("Received %d\n", sig);
}int main() {struct sigaction sa;sigset_t mask;sigemptyset(&mask);sigaddset(&mask, SIGINT);sigprocmask(SIG_BLOCK, &mask, NULL);sa.sa_handler = handler;sigaction(SIGINT, &sa, NULL);while(1) {printf("Waiting...\n");sigsuspend(&mask); // 安全等待信号 }
}

六、性能优化与避坑指南

  1. 信号处理黄金法则

  2. 精简处理函数:避免调用非异步安全函数

  3. 使用volatile变量:保证标志位的可见性

  4. 优先选择sigaction:确保可靠性和可移植性

  5. 注意信号队列:实时信号(SIGRTMIN+)支持排队

  6. 多线程慎用:每个线程有独立信号掩码

  7. 常见问题解决方案
    | 问题现象 | 解决方案 |
    |------------------------|------------------------------|
    | 僵尸进程堆积 | SIGCHLD+wait组合拳 |
    | 服务无法正常关闭 | 捕获SIGTERM实现优雅退出 |
    | 定时任务执行滞后 | 使用setitimer提高精度 |
    | 信号处理函数被重复调用 | 设置SA_NODEFER标志 |


附录A:僵尸进程回收代码示例

// SIGCHLD处理示例 
void sigchld_handler(int sig) {while(waitpid(-1, NULL, WNOHANG) > 0);
}int main() {struct sigaction sa;sa.sa_handler = sigchld_handler;sigaction(SIGCHLD, &sa, NULL);if(fork() == 0) {// 子进程逻辑 exit(0);}while(1) pause();
}
关键字:企业产品网络推广_海珠区疫情防控指挥部_免费的网络推广有哪些_免费关键词搜索引擎工具

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: