进程先识别信号,并要具备对应信号的处理方法
信号和信号量不同
信号量是实现进程同步的机制
信号
信号是软件中断,是一种事件通知机制,通知进程发生了某个事件,打断进程当前的操作,然后去处理这个事件
特征:
- 简单
- 不能携带复杂的信息
- 满足某个特定条件才能触发
信号处理方式初步理解
- 信号的产生是异步的,当信号产生的时候,对应的进程可能在做更重要的事情
- 进程可以暂不处理这个信号,不代表这个信号不会被处理
默认处理,忽略处理,自定义处理- 进程需要记住信号已经来了(有无信号,什么信号)
- 异步:进程运行和信号的产生互不干扰
同步:进程运行需要等待资源- 如何记住:
信号会记在pcb中
通过位图保存,信号产生对应的比特位变成1- 信号只能由OS设置
OS通过修改位图的比特位向某个进程写入信号
- 默认处理动作(就是执行该信号本身)
- 忽略(内核收到信号但是丢弃了)
- 捕捉(将信号重新定义,用户让干啥就干啥)
信号的机制
A给B发信号,B在接收到信号前执行自己的代码,收到信号后立即暂停去处理该信号
信号是一个软件中断:原因
- 操作系统给当前进程发送一个信号,该信号不是立即就被进程处理;
- 有一个处理标准,当前进程执行流进入内核执行内核代码时,再回到用户态前才会处理信号
- 所有信号的处理都是由内核发送和处理的
- 但是这个过程很短暂,用户察觉不到
硬件中断mmu:由硬件直接发出的指令
信号种类
操作系统定义的信号,共62个
非可靠信号(非实时信号):1~31
特点:不可靠,信号有可能会丢失可靠信号(实时信号):34~64
特点:可靠,信号不会丢失
收到信号立马处理
信号的生命周期
产生,注册,注销,处理
信号先注销再处理,防止重复处理信号
产生
按键产生
系统调用(函数)产生,kill,raise,abord
软件条件产生alarm
硬件异常产生(越界,非法内存访问)
命令产生kill
硬件产生
键盘产生的信号是由OS向进程发信号
用户不能直接访问OS内的数据
中断:
数据角度上外设是不和CPU直接交互,需要存储到内存经过计算再刷新到外设
硬件角度是可以的,CPU有很多针脚,可以接收外界的电脉冲信号,有特定的硬件设备给这些针脚发信号
数据通过网络发送出去后,OS如何知道网卡上有数据呢,OS是通过硬件中断的方式知道某些硬件就绪了
移动鼠标,按键盘,中断是硬件向CPU特定针脚发送电信号(通过8259收集外部硬件的电信号,转换成特定的中断编号)
CPU遇见中断就开始处理
软件上,OS在开机时会为每一个中断加载一张表(中断向量表,类似一个函数指针数组,下标对应的中断,内容指向的是一个方法),CPU就会找到对应的方法去处理
这张表是由OS维护的
ctrl +c | 2号信号触发的终止 |
---|---|
ctrl +| | 3号信号 |
ctrl +z | 20号信号SIGTSTP |
man 7 signal命令可以罗列出关于信号的内容
1号,term | 终止进程 |
---|---|
2号,Ign | 忽略该信号 |
3号,Core | 终止进程并产生核心转储文件 |
4号,Stop | 停止进程,让其在后台执行,按fg又回到前台 |
5号,Cont | 如果当前进程停止,则继续该进程 |
对于产生核心转储文件(coredump文件)有两个原因(用 ulimite -a命令):
- core file size为0,当前进程收到3号信号,让进程产生coredump文件,但是操作系统限制其产生的文件为0,也就是不让其产生转储文件
- core file size为ulimite,说明是无限制的,如果没有产生转储文件,其原因是磁盘空间不足
软件产生(通过系统调用接口完成信号发送过程)
命令:kill和kill -9;
- kill:向指定进程发送指定的信号
pid:要kill的进程号
sig:给当前进程发送的信号
kill函数用于终止所传进程号的进程,第一个参数传进程自己的pid则终止自己
raise函数
是用kill封装而成,谁调用谁就接收到信号终止自己
abort
使当前进程接收到信号而异常终止,发送一个6号SIGBART号命令
alarm函数
设定一个闹钟,告诉内核在几秒后给当前进程发送14号SIGALRM信号
该信号的默认处理动作是终止当前进程
- 该程序的alarm函数是直接将进程退出
- alarm函数常用于时间限制
进程崩溃
进程崩溃的本质是该进程收到了异常信号
- ÷0后:CPU内的状态寄存器会被设置成有错误,OS会结合报错原因构建信号向目标信号发送信号
- 越界/野指针:语言层面上使用的指针,都是虚拟地址,虚拟地址要被转成物理地址然后才能访问物理内存,才能读取物理数据和代码
虚拟地址有问题,由于地址转换是mmu(硬件,内存管理单元)+页表(软件)来做的,这个转换过程就有问题,这个问题表现在硬件上
OS发现问题后,就会把问题转换成信号发送给对应进程