Linux-信号产生

发布于:2024-05-10 ⋅ 阅读:(23) ⋅ 点赞:(0)

前言:关于信号的概念:http://t.csdnimg.cn/rUPxq

如果你并不了解信号,可以看一下上面的博客,这篇主要关于信号的发送

产生信号的四种方式:

  1. 键盘
  2. 系统调用接口
  3. 由软件产生信号
  4. 由硬件产生信号

1. 键盘

        CTRL+c:终止前台进程,向前台进程发送SIGINT

        CTRL+\:退出前台进程,向前台进程发送SIGQUIT

        本质是在按键盘的时候会产生键盘中断:

        键盘中断是指在计算机处理键盘输入时,键盘向计算机发出一个中断请求(IRQ),然后计算机暂停当前的任务,转而处理键盘输入。当键盘中断被触发时,CPU会保存当前程序的状态,然后跳转到处理中断程序。在处理中断程序中,操作系统将读取键盘输入,将其存储到缓冲区中,然后返回到原来的程序继续执行

        与键盘中断相关的硬件部分是由键盘控制器负责的。键盘控制器通过扫描矩阵式键盘的电路,检测是否有按键被按下,并将按键对应的编码发送给计算机。当键盘控制器检测到一个按键被按下时,它会向计算机发出一个中断请求。

        当键盘输入的内容被OS识别为上面两条指令时,OS就会通过系统调用发送给前台进程信号

2. 系统调用接口

        kill函数就是系统调用接口

函数功能:

        向指定进程发送指定信号

参数:

        pid:进程pid

        sig:信号编号

返回值:

        成功返回0,失败返回-1 

        c语言也封装出了一些函数 

函数功能:

        向自己发送指定信号

参数:

        sig:信号编号

返回值:

        成功返回0,失败返回非0

函数功能:

        向自己发送SIGSBRT(6号)信号,使自己这个进程终止并核心转储,abort(流产)

3. 由软件产生信号

        在之前学习管道的时候知道,管道是具有访问控制的,其中当读端关闭,写端还在继续写操作系统会识别并终止写端进程

        其实是操作系统识别到软件(管道)异常,通过发送SIGPIPE(13)信号的方式终止写端进程值得一提的是如果对信号捕捉,但是自定义处理动作中没有终止进程异常没有被处理,处理完信号返回时OS还是会检测到异常发出信号

        还有一种是闹钟

        调用alarm函数可以设定一个闹钟,也就是告诉内核在seconds秒之后给当前进程发SIGALRM信号, 该信号的默认处理动作是终止当前进程。

        可以signal(SIGALRM,函数回调)更改默认处理动作,在函数结尾重新设置alarm,实现循环

        子进程在终止或者暂停时都会向父进程发送SIGCHLD(17)信号,父进程可以通过信号自定义捕捉waitpid等待来回收子进程 

4. 由硬件产生信号

除0错误:

        当进程中有除0错误,当CPU执行到这条语句时,就会产生异常,OS识别异常后向该进程发送SIGFPE(8)信号Floating point exception(浮点数异常)

        OS会在CPU计算完毕后检测,如果发生除0就会得到无穷大的数,溢出,就会把状态寄存器(Bitmap)的状态标记位设为1,如果栈溢出标记位为1,OS会识别出栈溢出问题(SIGFPE),就要找到当前哪个进程在运行(PID),发送信号

        在硬件层面上,每次栈溢出标记位为1就不会再计算,OS会发送信号,切换到下一个进程,栈溢出标记位是上下文数据保存到对应的进程PCB中,如果异常没有被处理,下一次CPU计算时,栈溢出的标记位还是1,OS继续发信号

野指针:

        在野指针,指针越界的问题上,OS会识别并发送SIGSEGV(11)信号,Segmentation Violation(段冲突),其实是Invalid Memory Reference(无效内存引用)

        指针就是地址,为了找到目标位置

        语言上的地址是虚拟地址

        所以就需要从虚拟地址转换成物理地址

        转换是通过页表(软件)+MMU(Memory Manager Unit内存管理器单元,硬件)实现,他们记录了,进程对于该地址的读写权限

        当野指针越界非法访问,MMU在地址转换的时候就会通过权限查询,发现没有权限,进而报错,报错的内容保存在MMU中的寄存器中,OS通过访问该寄存器识别到错误(SIGSEGV),发送给当前非法访问地址的进程


网站公告

今日签到

点亮在社区的每一天
去签到