1. 信号量
信号量:
system V版本信号量:(并不能支持跨平台)
1. 本质: 是一个计数器(保存资源数量) + PCB等待队列(存放被阻塞的进程的PCB)
两个进程都想去访问临界资源(共享内存当中保存了一个变量shm_cout = 10), 一旦涉及
到修改变量shm_cout, 容易造成数据二义, 要访问依赖CPU, 帮我们进程A和进程B计算, A拿
着CPU去计算,先从共享内存读出变量的值, 放到寄存器当中, 寄存器 = 10, 想要执行10 +
1, 但被打断了,A把CPU让出来了, B拿去计算, 完成对变量的++, 又把CPU让出来, A要用
CPU计算,得先恢复现场, 而且寄存器的值还是10, ++后shm_cout变成11, 又回写到共享内存
中,
理论情况下, 进程A+1了, 进程B也加1了, 对于shm_cout理论上值应为12, 但是由于进
程A在+1时被打断了, 导致最终shm_cout的值为11
方案:
在访问临界资源之前, 先去获取一个信号量, 这样的一个信号量中有两个量(计数器和
PCB等待队列), 若资源中变量数变为2 ,则计数器的值+1也为2, 要拿信号量,需要对我们
的计数器进行预减操作, 1 --> 0,如果计数器的值大于等于0(x-1>=0),x>=1,>0, 也就
意味着资源是有空闲的, 我们进程是可以去获取资源的(对计数器减1, 访问临界资源), 如
果/当计数器的值是小于0的, 也就意味着资源不是空闲的, 进程不可用访问资源, 如果这
个时候还需要访问资源, 则将该进程的PCB放到PCB等待队列中, 当进程A把资源归还给共
享内存时, 将计数器当中的值进行+1, 然后唤醒PCB等待队列中的进程B
获取信号量:
1. 对信号量当中的计数器进行预减操作
如果计数器的值是大于等于0, 也就是意味着资源是有空闲的, 进程可以先去获取资源
对计数器进行减1操作之后, 去获取资源
如果计数器的值是小于0的, 也就是意味着资源不是空闲的, 进程不可以访问资源, 如果这个时候还需要访问资源,则将该进程的PCB放到PCB等待队列当中去.
归还临界资源:
将计数器当中的值进行加1操作, 唤醒PCB等待队列当中的进程
如何保证互斥:
只需要将信号量当中的计数器的值设置为1, 也就是意味着同一时刻只有一个进程可以访问到临界资源.
2. 进程信号:
1. 信号的基本概念
信号是进程之间事件异步通知的一种方式,属于软中断, 当一个进程收到一个信号的时候, 信号就会打断当前进程, 处理不
处理取决于内核(我们), 死了怪自己
红绿灯,释放的信号促使我们等待和通过, 通过这样的信号给我们传递信息, 撞死不负
责任(只是告诉信息,并没有拉住你) --> 软件中断
信号的种类:
linux操作系统中有62个信号(kill -l),
前31个(1-31): 不可靠信号, 非实时信号, 信号有可能会丢失,
后31个(34-64): 可靠信号, 信号不会丢失
2. 信号的产生方式
硬件产生:
ctrl + c: 给进程发送SIGINT信号, 这样的一个信号会导致进程退出;
相当于 kill + 信号序号 + 进程号
ctrl + z: 给进程发送SIGTSTP信号, 让一个前台进程放到后台, 并且进程状态为T, 暂停状态
ctrl + |: