齐齐哈尔建设局网站首页,上海市建设咨询协会网站,邢台做移动网站公司电话,中国著名设计师的推荐在我们使用Linux系统的时候我们经常会使用ctrl c的方式来终止进程#xff0c;也
会使用kill命令来杀掉进程#xff0c;评判进程退出的健康程度中也有信号的身影。那
么Linux中的信号到底是什么#xff1f;今天就由我来介绍Linux中的信号。1. 信号的概念
要了解计算机中的信…在我们使用Linux系统的时候我们经常会使用ctrl c的方式来终止进程也
会使用kill命令来杀掉进程评判进程退出的健康程度中也有信号的身影。那
么Linux中的信号到底是什么今天就由我来介绍Linux中的信号。1. 信号的概念
要了解计算机中的信号首先要认识生活中的信号。在我们的生活中信号时时刻刻在我们的身旁早起响的闹钟、上下课铃声起跑时的枪令、过马路时的红绿灯等等这些都是我们所能够接触到的信号。 那我们对这些信号的认知应该是什么样子的呢 首先就是我们应该认识它们知道它做出行为之后知道它的意思是什么我们知道我们的行为将是什么。 那就意味着我们在收到这个信号前我们就已经知道这个信号的处理方式了比如我们幼儿园时常教的红灯停绿灯行。 信号的到来我们并不清楚是什么时候信号到来相对于我现在的工作是异步产生的比如起跑时的枪令。 信号到来时我们并不一定要立即处理它我们会在合适的时候处理比如正在打游戏的时候我们的外卖来了。 那这也意味着我们要有一种存储这个已经到来的信号的能力。 以上就是对信号的认识而计算机中的信号也同样是遵循着以上规律 我们的Linux中就存在着这样的一张列表存储着Linux系统中所有的信号。而上面规律中的“我们”在计算机中指向的就是进程。稍后我会介绍Linux中是如何体现信号的规律的。 现在我们就能得出Linux中信号的定义 信号是向目标进程发送消息的一种机制。
2. 信号的产生
a. 关于进程的一些指令
当我们运行这样一段代码时 我们会发现当我们向命令行中输入命令时shell并没有做出任何反应。这是因为Linux中只能有一个前台进程对于前台进程我们可以使用ctrl c终止前台进程来让我们的命令输入再次有效 我们也可以将前台进程切换成后台进程让我们的命令可以使用 其中让进程后台运行的方式就是在后面加个取地址符号。 我们可以使用jobs查看后台进程 可以使用fg 后台进程编号将该进程切换为前台进程 可以看到我们的命令行中输入的命令又没有作用了。 我们也可以使用ctrl 暂停前台进程但是由于Linux中前台进程只能有一个所以我们需要将暂停的进程切换到后台然后使用bg 编号继续运行 那这段时间我们的shell去了哪里其实操作系统会在我们执行前台进程终止前台进程的过程中将shell不停的从前后台中进行切换。而判断一个进程是否是前台进程的依据之一就是这个进程能否有能力接收用户输入。操作系统它本质上也是一个软件那么操作系统运行软件管理进程操作系统又由谁来运行呢这个我们稍后再解释。
b. Linux中信号的灵感
不知道大家有没有想过这么个问题在我们使用键盘鼠标的时候计算机怎么就知道我们的键盘中有了数据需要读取呢难道是采用轮询的方式一直扫描机器的外设看看外设中是否有数据可读这种方式未免太消耗计算机的时间了。 我们知道计算机中的CPU主要是由两部分组成运算器和控制器。运算器主要是进行系统的运算而控制器有一部分作用就是控制外设CPU中存在着许多带着编号的针脚这些针脚可以理解为其中一部分直接连接着我们的外设其中肯定不是直接连接它们中间还有8259。这些针脚另一端就是寄存器当我们的外设有数据输入时它们会发送信息然后转化为光电信号传给我们的针脚另一端的寄存器中。而这些带有编号的针脚的编号也是有意义的计算机在启动的时候会生成一张表这张表中记录了外设的读方法所以当我们的外设有数据输入时也就是寄存器接收到光电信号时操作系统会让CPU执行那张表中的对应外设的读方法。而那张表其实也就是一个函数指针数组而访问对应的外设读方法也就是通过编号作为下标映射来访问。 这种通过外设发送信号给cpu然后操作系统再调用对应的读方法这种方法叫做中断。 针脚的编号我们叫做中断号而那张记录对应特定外设的表叫做中断向量表。 我们再次观察信号列表我们会发现它没有32和33号信号。其中1到31号信号成为普通信号后面的信号称为实时信号。我们主要研究普通信号。 对于普通信号而言当一个进程收到信号之后这个进程起码要表示它是否收到了这个信号。那么如何表示呢它会在进程pcb结构体中维护一个位图位图的1/0表示信号的有无位图的位数表示信号的编号那么有了信号我们还应该知道对应信号的处理方式而我们的每一个进程也都会有一个函数指针数组里面记录了收到对应信号的处理方式而信号的编号也跟这个数组的下表是对应的。 了解以上流程之后我们发现键盘读数据的方式好像和信号的处理方式有些相似。其实Linux中的信号就是根据中断技术模拟实现的只不过信号的中断更多是软件层面的。
c. 信号的产生方式
1). 键盘产生
我们所使用的ctrl c等等我们发现它不会被操作系统识别为简单的输入而是以组合键的形式输入。其实它们会被处理成信号例如ctrl c终止前台进程对应二号信号ctrl z暂停前台进程19号进程还有一个ctrl \终止前台进程三号信号。 我们可以验证以上说法 我们对于信号的处理有三种方式默认处理方式忽略和自定义处理而这个signal函数就可以实现自定义处理它的第一个参数是对应自定义的信号编号第二个参数是一个函数指针记录着用户自定义处理的方式。我们可以使用这个函数来验证以上说法
我们先用对应的信号分别终止进程 然后我们使用组合键终止进程 ctrl c ctrl ctrl z 我们发现组合键终止或暂停程序确实是对进程发送了信号但是我们也发现19号信号好像没有被修改自定义这是因为信号中有一些信号是不可被修改的这样的信号还有9号信号等等。 我们可以使用man 7 signal查看信号的默认行为 其中Core和Term一般都是终止进程的意思
2). 系统调用
有一些系统调用也可以产生信号。 abort 这个就是直接终止自己了。对应六号信号 raise 它可以指定信号让操作系统发送给自己。 c. 异常
当我们的代码中出现除零或者访问空指针的时候就会出现错误操作系统就会给我们发送信号终止进程 对应我们八号信号。 对应11号信号。 对于空指针错误来说我们访问了0地址那里本来就是不可被访问的就算能访问也会由于页表中没有相应的映射从而触发中断引起异常。我们知道cpu中会读取我们地址空间的地址进而将地址空间转化为物理地址再去内存中读取那么这个转化的过程就由CPU中一个叫MMU的东西来进行它其中会有一个标志位来记录是否转化异常如果异常的话它会置为1操作系统就会检测到这个标志位然后向该进程发送信号终止该进程。 对于除零错误为什么会除零错误原因是数学层面不允许除零除零无意义但是计算机是怎么处理的呢我们的CPU中会有一个寄存器status它表示了该次运算的健康程度当除零时它的身上也会有一个标志位叫做溢出标志位会被置为1操作系统得知后它就会给对应进程发送信号终止该信号那么此时我们就会有一种有意思的现象 我们这个程序中可是没有循环的但是其中却出现了循环的现象。这是因为我们修改了八号信号的处理方式改为自定义捕的方式而自定义方式中并没有直接退出进程。那么本来操作系统当看到status寄存器中的溢出标志位为1之后就会向该进程发送八号信号终止该进程然后继续调度其他进程我们知道进程的调度就是将寄存器中的内容也就是硬件上下文切换为其他进程的。我们并没有退出这个进程所以当我们再次调度这个进程的时候status寄存器中的溢出标志位仍是1那么操作系统仍旧会发送八号信号给该进程。这就是为什么会造成循环的原因。 这是硬件方面的异常。还有软件方面的那就是管道当读端管道关闭之后写端进程会直接收到操作系统的13号信号而直接关闭。
d. 软件条件
我们上面所谈论的都是程序出了问题之后再终止程序的但是也有些是不是因为出现问题需要终止进程的而是特定的做某些事比如在一个时间段做某些事那么这时候就有了一个信号 14号信号也就是闹钟它也有一个接口 这个接口的意思就是在进程启动seconds秒之后终止进程默认。 我们的众多进程中可能会有多个进程使用闹钟那就意味着闹钟也是需要被管理的管理的方式肯定还是先描述再组织我们可以大概想想这个结构体中应该会有什么进程的pid、闹钟的目标时间、等等。我们的时间总要有个参照物那就是时间戳。那如何管理呢用链表的形式每秒遍历吗操作系统不会做这种低效率的事情。所以我们可以采用小根堆的形式每次只要查看堆顶的时间到了没就可以管理好所有的闹钟了。 而我们利用闹钟也可以发现一些现象 稍加修改 从这其中我们也可以看到与硬件大量交互的速度相比于CPU有多慢了。 以上就是信号产生的几种方式我们可以看到无论信号以何种方式产生最终都是由操作系统发送信号给对应进程这是因为操作系统是进程的管理者。
3. 操作系统运行的原理
我们操作系统可以调度所有进程运行程序等等一系列工作那操作系统本身也是一个软件它也是一个进程啊它又由谁来运行呢 其实操作系统它就是一个死循环它会在做好所有前置准备之后进入死循环然后开始调度运行其他进程。 我们前面说了CPU中有针脚会连接外设利用中断的技术进程外设数据的读取。而还有一个针脚它连接着一个装置这个装置它又连接着我们的时钟芯片。 我们的电脑在关机几个星期你打开之后它的时间可能还是正确的那如果你关机几年呢就不一定了那为什么我们的电脑关机之后我们再打开我们的电脑的时间还能是正确的呢这就是因为我们的计算机中有些设备是有自己的小电源的类似于时钟芯片它就会有自己的供电方式一个小的纽扣电池。 我们上面的装置叫做CMOS它会根据时钟芯片来以周期的非常高频的时钟中断的方式来一直刺激CPU它既然连接了针脚那它就会有对应中断向量表中的读方式但是这里并不是读的方式而是操作系统的调度其他进程的方式也就是操作系统的代码而其中的高频也叫主频也是衡量计算机性能的一个标志。这样我们的的操作系统就会一直被CPU所运行它是由硬件来催动着它运行的。我们所说的操作系统的前置准备其中有一个就是中断向量表的构建。而这个前置准备也叫做各种中断的陷阱的初始化工作。所以操作系统的执行是基于硬件中断的。