进程之间的制约关系有两种:同步与互斥
为什么需要互斥
因为操作系统会调度进程,并且有多个处理器在运行不同的进程,使得多个线程并发执行,可能导致同时访问共享变量、共享资源等临界资源,这样会导致不可预知的后果,所以需要互斥访问。
哪些情况下会发生进程调度:
主动放弃:需要等待其他条件;任务完成了
某些原因引起其他线程从其他状态转为就绪状态:中断完成;某些资源被释放
进程优先级变化:时钟中断时发现当前线程的时间片用尽,导致优先级降低等
怎么实现互斥
因为并发访问的原因有:多处理器,线程调度,所以需要从这两点入手解决互斥问题:
1. 屏蔽中断:多处理器无效,单处理器有效。在单处理器中,屏蔽中断就可以导致进程一直占有处理器
2. 原子操作:需要处理器硬件支持,将几个命令合并成一个命令。适用范围有限。
这两种都不太理想,所以提出了信号量机制,这是用软件的方式解决互斥问题,但信号量机制的实现也是依靠屏蔽中断或者原子操作完成的。
信号量机制由“信号量”和“P操作、V操作”两部分组成。信号量(s)为一个整型变量,只能被两个标准的原语所访问,分别记为P操作和V操作,定义为:
P(S) {
while( S < 0 );
S--;
}
V(S) {
S++
}
解决临界段问题的有关硬件方法及信号量机制所描述的P,V操作,都存在“忙等待”(busy-waiting)现象。即如果某一个进程正在执行其临界段,其他欲进入临界段的进程均须在它们的entry code中连续地循环等待(如执行while(condition);语句等)。这种循环等待方式实现的互斥工具又称为自旋锁(Spinlock)。
该处理方式下,如果能够很快走出循环,进入临界段(如相关临界段很短,其他进程很快走出临界段)则是可取的;但是如果相关临界段很长,势必使欲进入临界段的进程可能要长时间循环等待其他进程走出相关临界段,这样会浪费宝贵的处理机时间,其他已经在临界段的进程也不能及时得到处理机运行。
为克服信号量机制中的“忙等待”,可重新定义P,V操作。在某个进程执行P操作过程中,若发现信号量的状态不允许其立即进入临界段,则P操作应使该进程放弃CPU而进入约定的等待队列(调用系统函数block())。当某个进程执行V操作时,如果在该信号量上有被阻塞的等待进程,则V操作负责将其唤醒(调用系统函数wakeup())。
网友评论