文章目录
- 序:在我们的生活中,有很多信号,比如红绿灯,快递取件码等,所以从本章开始,我们将了解进程信号中的信号,我们会知道什么是信号,信号又是怎么产生的,了解信号,为后续的学习做铺垫!!!
1. 信号的概念
1.1 信号
问题一:生活中有哪些代表信号的东西呢?
信号弹、红绿灯、狼烟、闹钟等,但是信号产生后,我们可能并不会立即处理这个信号,因为此时我们可能正在做更重要的事情—信号产生后到信号处理之间一定会有一个时间窗口,不一定会及时处理!!!但在这个时间窗口内,你必须记住这个信号。
1.2 认识信号
问题一:什么是认识信号?
1.识别信号
2.知道信号的处理方法
1. 进程必须能识别和处理信号—即使信号没有产生,也要具备处理信号的能力—信号的处理能力,属于进程内置功能的一部分
2. 进程即便是没有收到信号,也能知道哪些信号该怎么处理
3. 当进程真的收到了一个具体的信号时,进程可能并不会立即处理这个信号,在合适的时候回去处理
4. 一个进程必须当信号产生,到信号开始被处理,就一定会有一个时间窗口,进程具有临时保存哪些信号已经发生了的能力
问题二:为什么Ctrl+c能够杀死前台进程呢?
当我们想要终止一个进程时,我们会按 ”ctrl+c“ 键或者 ”ctrl+/“ 键,但为什么输入这样的键后,进程就退出来了,这是因为ctrl+c就是向当前进程中传入一个2号信号SIGINT信号。
Linux中,一次登录,一个终端,一般会配上一个bash,每一个登录,只允许一个进程是前台进程,可以允许多个进程是后台进程。
当一个进程变成后台运行,此时Ctrl+c将不会被那个后台进程收到,而是发给了bash进程了,但是bash内对ctrl+c进行了处理,所以不会退出。
Ctrl+c本质是被前台进程解释成为收到了信号,2号信号。进程收到2号信号的默认动作就是终止自己。
信号图:
这张图中一共有62个信号,其中没有0号信号,没有32,33号信号
其中1~31号信号—普通信号
34~64—实时信号(出现了,就要立即处理)
信号的处理方式:
1. 默认动作
2. 忽略
3.自定义动作(信号的捕捉)
1.3 signal函数
这个函数是用来修改特定进程对于信号的处理动作的。
不想让收到信号的进程执行默认动作,就将自定义动作的函数传到这个signal函数的第二个参数中,其中该函数指针的int参数,就表示收到了哪一个信号。
在一个进程中,只要signal函数被设置了,在该进程的生命周期内,该函数一直生效。
1.4 信号的识别(硬件角度)
问题一:从硬件的角度谈谈,键盘数据是如何输入给内核的?ctrl+c又是如何变成信号的?
键盘被按下后,肯定是操作系统先知道!操作系统是怎么知道键盘上有数据了??
在开机的时候,操作系统会自动加载进内存中,当我们将数据从键盘输入,并按下回车键发送时,键盘会向CPU的针脚发送一个硬件中断的信息,这个中断信息会保存在CPU的寄存器中,此时操作系统可以从CPU的寄存器中获取这个中断信息,当操作系统拿到后,操作系统会去中断向量表中找到与这个中断信息对应的下标,然后通过这个下标内存储的方法,实现将键盘中的内容拷贝到文件缓冲区中,在拷贝之前,操作系统会判断数据,如果是像ctrl+c这样的数据,操作系统就会将这个ctrl+c转化为2号信号发送给进程。(所以键盘是基于硬件中断来传数据的)
问题二:什么是回显?
当我们向键盘中打印数据时,键盘会将数据写入到他自己的文件缓冲区中,如果我们要将输入键盘的数据打印到显示器上,就是是将键盘的文件缓冲区中的内容拷贝到显示器当中的文件缓冲区内,从而被显示器打印,而这个过程就叫做回显!!!而其他的设备若也想将数据打印到显示器上,也必须将数据拷贝到显示器的文件缓冲区内!!!
2. 信号的产生
2.1 键盘组合键
ctrl+c:2号信号SIGINT
ctrl+\:3号信号SIGQUIT
ctrl+z:19号信号SIGSTOP
2.2 kill命令
kill -signo +[pid]
2.3 系统调用
kill函数:
raise函数:
其中raise(sig)=kill(getpid(),sig)
abort函数:
abort—>给自己的进程发送6号信息,就直接退出来了。
2.4 异常
问题一:为什么(除0错误、野指针等问题)是由操作系统给进程发送信号?
在CPU中,进程的上下文会被放入CPU的eip寄存器当中,所以能知道进程当前的异常信号,CPU也是硬件,而操作系统就是硬件的管理者,所以操作系统也能知道该进程当前的异常信号是什么,而且,只要这个进程没有退出,或者这个错误没有被修复,那么只要轮转到该进程时,操作系统就会一直报错!!!而且用户层没办法去系统层面修改,用户只能捕捉,操作系统只是让用户知道问题在哪而已。
以野指针为例,当我们用这个野指针时,本质是将该指针的虚拟地址转化为物理地址,但是这个地址转化失败了,于是就被失败的信息就会保存在CPU的某个寄存器中,引发硬件报错,然后被操作系统知道。
总结:信号的产生方式!但是无论信号如何产生,最终一定是操作系统发送给进程的,因为操作系统是进程的管理者。
2.5 软件条件
问题一:异常只会由硬件产生吗???
在读写过程中,当我们将读端关闭,写端就会报错(SIGPIPE),然后被操作系统杀死。又比如这个4号文件没有打开,却往里面读取数据。
3. core dump
Core dump:core/term
默认云服务器上面的core,功能是被关闭的!!!
打开系统的core dump功能,一但进程出异常,操作系统会将进程在内存中的运行信息,给dump(转储)到进程的当前目录(磁盘)形成core pid文件(这样我们就知道运行时的错误在哪一行报错了!!!),因为核心转储(core dump)。
Ulimit -a查看
Ulimit -c开启
开启后,直接复现问题之后,直接定位到出错行,先运行,在core-file:事后调试
总结:
本篇文章讲述了信号的概念与信号的五种产生方式,从硬件的角度讲述了信号的识别的原理,还引入了core dump的概念,加深了对信号的理解。