信号的概念与相关知识认识
信号是向目标进程发送消息通知的的一种机制。 信号可以以异步的方式发送给进程,也就是说,进程无需主动等待,而是在任何时间都可以接收到信号。
信号的种类
用kill-l命令查看系统定义的信号列表:
前台进程和后台进程的认识
我们首先要知道,打开xshell软件时,默认就已经执行了shell进程,而这就是前台进程,而且前台进程只有一个。当我们运行一个我们写的死循环进程时:
#include <iostream>
#include <unistd.h>
using namespace std;
int main()
{
while(1)
{
cout << "haha" << endl;
sleep(1);
}
return 0;
}
其实此时该进程就自动变成了前台进程,而操作系统会自动的将shell切换成后台进程。而且此时我们呢无论输入什么指令都不会被执行,因为我们所输入的指令默认都会被前台进程接收。但是我们可以通过kill -9 进程pid和Ctrl c来终止此前台进程,终止以后,操作系统还会自动的将shell设置为前台进程。记住Ctrl c并不能终止前台进程shell。
如何生成后台进程
如果我们想要将进程执行成后台进程的话可以在运行进程的后面加上&符号:
而对于这两个数字对应的分别就是:后台进程编号和该后台进程pid。
而且我们可以同时可以执行多个后台进程。
查看后台进程
通过jobs指令查看后台进程:
后台进程与前台进程的转换
通过fg(front ground)+后台进程编号将后台进程变成前台进程:
通过Ctrl z指令和bg(back ground)+暂停进程编号将前台进程变成后台进程:
我们可以通过Ctrl z将前台进程暂停,但是我们的前台必须要有进程执行,否则系统就会挂掉了,此时操作系统会默认将shell设置为前台进程,因此原先的前台进程就被暂停在了后台中。
信号中断过程
操作系统通常通过硬件中断机制来确定外设是否有数据可用。中断是计算机系统中的一种重要机制,它是指在计算机执行某个任务时,由于发生了某种特殊事件或接收信号时,硬件或软件会中断当前任务的执行(并保存当前的程序状态,如程序计数器、寄存器中的值等),转而去处理需要优先处理的事件或任务。中断可以打破程序的顺序执行,提供了一种异步(随时)处理的方式。而且中断处理程序执行结束后(如果没有异常退出),处理器会恢复之前保存的上下文,继续原来的任务执行。
我们知道CPU包括运算器和控制器的,对于控制器其实就是其他设备的控制的(数据层面上CPU并不会和外设交互,但是要控制信息,所以此时是会和外设交互)。CPU自身会提供一个个从0开始编号的针脚。针脚是和主板直接相连,而主板上插入着很多的硬件电路(相当于USB口)。而这些硬件电路就和我们的外设直接关联着。
当我们的外设在向CPU发送数据(触发中断)的时候,此时对应的针脚就会接收外设传来的高电频,从而点亮针脚(只有能进行IO的外设才能向CPU发消息的)。而我们的每个针脚都有对应的编号(中断号),所以此时的编号就会被写到CPU的寄存器里。那么寄存器里的数据就可以被程序读取了。而我们外设从对应针脚向CPU发送数据时的针脚号其实就是中断号。
因为每一个外设的中断号都是不一样的,所以通过中断号就可以知道具体是哪一个外设发送的中断。而为了更快地对每一个中断进行响应,每一个外设(可以向CPU发送中断)都有自己对应的中断处理方法也就是一张中断向量(函数指针数组)其中存储的是对相应中断处理的方法。
信号的产生
键盘产生
信号可以通过键盘产生。当我们运行一个死循环程序时,按住Ctrl c(其实就是发送2号信号)组合键时就可以中断进程。我们一般在shell上输入的指令都会放到进程的缓冲区中进行读取,而当我们输入Ctrl c组合键,并没有将数据输入给进程缓冲区中。而是被识别成为信号。
我们操作系统会维护每一个进程的信号处理函数表,用于记录进程为各种信号进行处理的指定函数。同时也可以提供信号的自定义处理方法()。