Linux进程信号详解(一):信号快速认识
一、信号快速认识信号现实生活中闹钟、红绿灯、上课铃声、狼烟、电话铃声、肚子叫、敲门声、脸色不好 ....1.1 生活中的信号 —— 快递的例子想象你网购了很多商品你能识别快递你知道快递员打电话时该怎么处理。即使快递没有到来你也知道快递来临的时候你该如何处理快递 。 —— 这是内置的识别能力。信号产生前你就知道处理方法即使快递没到你也知道“收到快递要拆开” —— 进程在信号产生前就已经准备好了处理函数。不必立即处理你正在打游戏可以5分钟后下楼取快递 ——信号不要求立即处理而是在“合适的时候”处理。记住有信号你知道有一个快递到了但还没取 —— 进程会保存未决信号。处理方式有三种默认动作开心拆快递自定义动作买了零食分给同学一些忽略不理快递基本结论识别信号是内核程序员内置的特性。信号产生前进程已经知道如何处理。信号处理不是立即的而是在合适的时候从内核态返回用户态时。信号到来 → 信号保存 → 信号处理。信号处理方式忽略 ; 默认 ; 自定义【后续都叫信号捕捉】快递到来的整个过程对你来说是异步的 你不确定 快递员什么时候会给你打电话1.2 键盘产生的信号MakefiletestSign:testSign.cc g -o $ $^ -stdc11 .PHONY:clean clean: rm -f testSigntestSig.cc#include iostream #include unistd.h int main() { int cnt 0; while (true) { std::cout hello world, cnt std::endl; sleep(1); } return 0; }ctrl c , 是给目标进程发送信号的 。 相当一部分的信号处理动作 就是让进程自己终止1.3 信号都有哪些kill -l 查看信号列表【数字大写的信号名】关键说明每个信号都有编号和宏定义名称如 2 号信号对应 SIGINT宏定义在signal.h头文件中34 及以上为实时信号用于实时进程通信日常开发主要使用 34 以下的常规信号每个信号都有默认处理动作可通过man 7 signal查看详细说明如 SIGKILL 的默认动作是终止进程且无法被捕捉和忽略。常用信号编号名称默认动作含义2SIGINT终止终端中断CtrlC3SIGQUIT终止Core Dump终端退出Ctrl\9SIGKILL终止强制终止不可捕捉、不可阻塞11SIGSEGV终止Core Dump段错误非法内存访问14SIGALRM终止闹钟信号20SIGTSTP停止进程终端停止CtrlZctrl c : 给目标进程发送 2信号 收到信号处理动作捕捉1.4 证明ctrlc - 二号信号修改一下testSig.cc的代码#include iostream #include unistd.h #include signal.h void handlerSig(int sig) { std::cout 获得了一个信号: sig std::endl; } int main() { signal(SIGINT,handlerSig); int cnt 0; while (true) { std::cout hello world, cnt std::endl; sleep(1); } return 0; }二、前台 后台进程2.1 现象查看2.2 核心定义特性前台进程 (Foreground)后台进程 (Background)标准输入✅ 独占键盘输入❌ 无法从 stdin 读取标准输出✅ 可以输出到终端✅ 可以输出到终端键盘信号✅ 响应 CtrlC 等❌ 不响应键盘信号数量限制必须只有一个可以有多个创建方式./program./program 前台进程唯一能接收键盘输入、获取标准输入的进程同一时间 Shell 中只能有一个前台进程。后台进程无法从键盘获取标准输入的进程同一时间可以有多个后台进程。Shell 命令行进程本身默认是前台进程负责接收用户输入的命令。2.3 为什么前台进程只能有一个键盘只有一个输入数据一定是给一个确定的进程的这是硬件层面的限制——键盘是独占设备。如果多个进程同时等待键盘输入操作系统无法决定把按键发给谁。因此 Shell 设计了作业控制Job Control机制前台作业当前与终端交互的进程组后台作业在后台运行不占用终端输入2.4 进程状态转换与作业控制命令命令作用示例jobs查看所有后台任务[1] Running ./test fg %n将后台任务 n 提到前台fg %1bg %n让暂停的后台任务继续运行bg %1CtrlZ暂停当前前台进程放入后台进程变为 StoppedCtrlC向前台进程发送 SIGINT 信号终止进程2.5 关键场景孤儿进程与后台化# 场景1正常前台进程 $ ./testsig # bash 子进程作为前台进程 # CtrlC 可以终止因为键盘信号发给前台进程 # 场景2后台运行 $ ./testsig # 立即放入后台 # CtrlC 杀不掉因为键盘信号只发给前台进程父进程先退出 → 孤儿进程自动后台化// 代码逻辑示意 int main() { if (fork() 0) { // 子进程 sleep(10); // 模拟工作 } else { // 父进程先退出 exit(0); } }现象父进程bash 的子进程先退出子进程变成孤儿进程被 init/systemd 收养自动提到后台因为失去了控制终端的前台关联CtrlC 杀不掉已经是后台进程
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2483946.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!