Linux进程信号--0、序章
目录
一、认识信号
1.1生活中的信号
1.2代码中的信号
1.3 后台进程操作(扩展)
二、信号概念
2.1查看信号
2.2查看各信号默认处理动作
三、信号处理
3.1默认行为(SIG_DFL)
3.2忽略行为(SIG_IGN)
3.3自定义行为(信号捕捉)
四、横向了解信号
一、认识信号
1.1生活中的信号
你在⽹上买了很多件商品,再等待不同商品快递的到来。但即便快递没有到来,你也知道快递来临
时,你该怎么处理快递。也就是你能“识别快递”
识别信号是内置的,进程识别信号,是内核程序员写的内置特性。
当快递员到了你楼下,你也收到快递到来的通知,但是你正在打游戏,需5min之后才能去取快递。那么在在这5min之内,你并没有下去去取快递,但是你是知道有快递到来了。也就是取快递的⾏为并不是⼀定要⽴即执⾏,可以理解成“在合适的时候去取”。
信号的处理⽅法,在信号产⽣之前,已经准备好了
在收到通知,再到你拿到快递期间,是有⼀个时间窗⼝的,在这段时间,你并没有拿到快递,但是
你知道有⼀个快递已经来了。本质上是你“记住了有⼀个快递要去取”
信号保存
当你时间合适,顺利拿到快递之后,就要开始处理快递了。⽽处理快递⼀般⽅式有三种:1. 执⾏默
认动作(幸福的打开快递,使⽤商品)2. 执⾏⾃定义动作(快递是零⻝,你要送给你你的⼥朋友)
3. 忽略快递(快递拿上来之后,扔掉床头,继续开⼀把游戏)
信号处理:a.默认 b.忽略 c.⾃定义, 后续都叫做信号捕捉
快递到来的整个过程,对你来讲是异步的,你不能准确断定快递员什么时候给你打电话
1.2代码中的信号
⽤⼾按下 Ctrl+C ,这个键盘输⼊产⽣⼀个硬件中断,被OS获取,解释成信号,发送给⽬标前台进程前台进程因为收到信号,进⽽引起进程退出Ctrl+C 的本质是向前台进程发送 SIGINT 即 2 号信号,我们证明⼀下,这⾥需要引⼊⼀个系统调⽤函数singal
//NAME
//signal - ANSI C signal handling
//SYNOPSIS#include <signal.h>
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);//参数说明:
signum:信号编号[后⾯解释,只需要知道是数字即可]
handler:函数指针,表⽰更改信号的处理动作,当收到对应的信号,就回调执⾏handler⽅法
改变ctrl + c信号所对应的函数执行方法
#include <iostream>
#include <unistd.h>
#include<signal.h>void handler(int signum)
{std::cout << "Get a signal :" << signum << std::endl;
}int main()
{::signal(2,handler);while(true){std::cout << "I am a process, I am waiting signal!" << std::endl;sleep(1);}// while(true)// {// std::cout << "I am a process, I am waiting signal!" << std::endl;// sleep(1);// }
}
要注意的是,signal函数仅仅是设置了特定信号的捕捉⾏为处理⽅式,并不是直接调⽤处理动作。如果后续特定信号没有产⽣,设置的捕捉函数永远也不会被调⽤!!Ctrl-C 产⽣的信号只能发给前台进程。⼀个命令后⾯加个&可以放到后台运⾏,这样 Shell不必等待进程结束就可以接受新的命令,启动新的进程。./sig &
Shell可以同时运⾏⼀个前台进程和任意多个后台进程,只有前台进程才能接到像 Ctrl-C这种控制键产⽣的信号。前台进程在运⾏过程中⽤⼾随时可能按下 Ctrl-C ⽽产⽣⼀个信号,也就是说该进程的⽤⼾空间代码执⾏到任何地⽅都有可能收到 SIGINT 信号⽽终⽌,所以信号相对于进程的控制流程来说是异步(Asynchronous)的。
1.3 后台进程操作(扩展)
// & 执行程序后使程序从前台转到后台,CTRL + c 无法后台杀掉进程./sig &// fg 将后台进程移到前台fg [1]//nohup将后台文件打印操作向nohup文件中打印nohup ./sig &
二、信号概念
信号是进程之间事件异步通知的⼀种⽅式,属于软中断。
2.1查看信号
kill -l
每个信号都有⼀个编号和⼀个宏定义名称,这些宏定义可以在signal.h中找到数字与信号对应
2.2查看各信号默认处理动作
man 7 signal
三、信号处理
3.1默认行为(SIG_DFL)
#include <iostream>
#include <unistd.h>
#include<signal.h>
#include<sys/types.h>void handler(int signum)
{std::cout << "我是: " << getpid() << ", 我获得了⼀个信号: " << signum << std::endl;
}int main()
{::signal(SIGINT,SIG_DFL);while(true){std::cout << "I am a process, I am waiting signal!" << std::endl;sleep(1);}// while(true)// {// std::cout << "I am a process, I am waiting signal!" << std::endl;// sleep(1);// }
}
3.2忽略行为(SIG_IGN)
#include <iostream>
#include <unistd.h>
#include<signal.h>
#include<sys/types.h>void handler(int signum)
{std::cout << "我是: " << getpid() << ", 我获得了⼀个信号: " << signum << std::endl;
}int main()
{::signal(SIGINT,SIG_IGN);while(true){std::cout << "I am a process, I am waiting signal!" << std::endl;sleep(1);}// while(true)// {// std::cout << "I am a process, I am waiting signal!" << std::endl;// sleep(1);// }
}
3.3自定义行为(信号捕捉)
#include <iostream>
#include <unistd.h>
#include<signal.h>
#include<sys/types.h>void handler(int signum)
{std::cout << "我是: " << getpid() << ", 我获得了⼀个信号: " << signum << std::endl;exit(0);
}int main()
{::signal(SIGINT,handler);// ::signal(SIGINT,SIG_IGN);// ::signal(SIGINT,SIG_DFL);while(true){std::cout << "I am a process, I am waiting signal!" << std::endl;sleep(1);}// while(true)// {// std::cout << "I am a process, I am waiting signal!" << std::endl;// sleep(1);// }
}
四、横向了解信号
以时间横向看信号分为信号产生,信号保存与信号处理。