进程间通信

来源:互联网 发布:2016年进口粮食数据 编辑:程序博客网 时间:2024/06/05 13:30

进程间通信

一.基本概念

竞争条件(race conditions):两个或多个进程读写某些共享数据,而最后的结果取决于进程运行的精确时序,称为竞争条件。

互斥(mutual exclusion):即某种手段以确保当一个进程在使用一个共享变量或文件时,其他进程不能做同样的操作。

临界区(critical region):对共享内存进行访问的程序片段。

适当的安排两个进程不可能同时处于临界区可以避免竞争条件,但并不能保证并发进程能正确高效的进行,一个好的解决方案,需要满足一下四个条件:

1. 任何两个进程不能同时出入临界区

2. 不应对CPU的速度和数目做出任何假设

3. 临界区外的进程不能阻塞其他进程

4. 不得使进程在临界区外无休止的等待

二.互斥的实现方案:

1.禁用中断

每个进程进入临界区后禁用所有中断,在离开之前再开中断。赋予用户进程关闭中断的权利是不明智的,但对于内核本身来说是极为方便的。

2.严格轮换法

int turn=0; //全局变量//进程0while(TRUE){while(turn!=0) ; //waitcritical_region();turn=1;Noncritical_region();}//进程1while(TRUE){while(turn!=1) ; //waitcritical_region();turn=0;Noncritical_region();}

严格轮换法持续的检测某一个变量,直到它具有某一特定的值(忙等待),因此浪费了CPU时间。

再者严格轮换法要求二个严格地轮流进入临界区,若二个进程一个快一个慢,则快的进程可能被处于非临界区的慢进程阻塞。所以,严格轮换法不是一个好的备选方案。


3.Peterson解法

#define FALSE 0#define TRUE 1#define N 2int turn;Int interested[N];void enten_region(int process){int other;other=1-process;interested[process]=TRUE;turn=process;while(turn==process && interested[other]==TRUE) ;}void leave_region(int process){interested[process]=FALSE;}


4.TSL指令

TSLtest and set lock)指令的工作流程如下:它将一个存储器字读到一个寄存器中,然后在该内存地址上存一个非零值。读数和写数操作保证是不可分割的-即该指令结

束之前其他处理机均不允许访问该存储器字。执行TSL指令的CPU将锁住内存总线以禁止其他CPU在本指令结束之前访问内存

为了使用TSL指令,我们要使用一个共享变量lock来协调对共享内存的访问。当lock0时,任何进程都可以使用TSL指令将其置为1并读写共享内存。当操作结束时,进程用一条普通的MOVE指令将lock重新置为0

enter_region:tsl register ,lock //取出lock的值,并将lock设置为1cmp register, #0 //lock原先是否为0jne enter_region //不为0则循环测试ret//返回,进入临界区leave_region:move lock , #0 //将锁值设为0ret



5.唤醒与睡眠

Peterson解法和TSL解法都会产生忙等待,使CPU效率降低,还会引起优先级反转问题(priority inversion problem)。

sleep系统调用将引起调用进程阻塞,wakeup系统调用则用于唤醒进程。

考虑当wakeup唤醒一个未阻塞的进程时,导致唤醒信号丢失。可以使用信号量(semaphore)累计唤醒次数供以后使用。

对于信号量可以使用一下两种操作:

DOWN:若其值大于0,则将其减一并继续。若值为0,则进程休眠。

UP:递增信号量的值,若有一个或多个进程在信号量上休眠,无法完成DOWN操作,则系统选择一个并允许其完成DOWN操作,信号量值仍为0

DOWNUP操作均为不可分割的原子操作。

原创粉丝点击