进程同步
- 所谓进程同步是指在异步环境下的一组并发进程因直接制约而相互发送消息,互相组合、互相等待,使得各进程按一定的执行速度进行,称为进程同步
两种形式的制约关系
- 间接相互制约关系(互斥关系)
多程序在并发执行时,要共享系统资源(临界资源),这些并发执行的程序会形成相互制约的关系,这些称之为互斥关系
- 这种关系类似于借书,一本书借走,另一个人则不能继续借阅,这就是互斥关系
- 直接相互制约关系(同步关系)
为了完成某项任务,会建立两个或多个进程,这些进程为了任务而互相合作。进程间的直接制约关系源于它们之间的相互合作,该关系称为同步关系
- 这种关系类似于同学间的传球比赛,一个人传球给另一个人,这体现了合作,也就是同步关系
临界资源
许多硬件资源如打印机、磁带机等,进程在使用它们时都需要采用互斥方式。其既可以是硬件资源,也可以是软件资源(共享变量、文件等)
进程同步的案例一:生产者—消费者
生产:in
消费: out
临界资源:counter
循环队列:buffer数组
缓冲池: n值
下面是两个进程
int in=0,out=0,counter=0;
item buffer[n];
void producer(){
while(1){
producer an item in nextp;
、、、
while(counter==n)//满
buffer[in]=nextp;//等待consumer取走后执行生产
in=(in+1)%n;
counter++;
}
};
void consumer(){
while(1){
while(counter==0);
nextc=buffer[out];
out=(out+1)%n;
counter--;
consumer the item in nextc;
}
};
这两个操作用汇编语言
register1=counter;
register1=register+1;
counter=register;
register2=counter;
register2=register2-1;
counter=register2;
临界区问题
while(TRUE)
{
进入区
临界区;
退出区
剩余区;
}
同步机制:
软件同步机制
Peterson解决方案要求两个进程共享两个变量
int turn;
boolean flag[2];
do{
flag[i]=TRUE;
turn = j;
while(flag[j]&&turn == j);
临界区;
flag[i]=FALSE;
剩余区;
}while(TRUE);
硬件同步机制
1关中断:会影响效率,不适用多CPU系统
2.利用Test-and-Set指令实现互斥
boolean TS(boolean *lock)
boolean old;
old=*lock;//lock=FALSE,资源空闲,lock=TRUE,资源正被使用
*lock=TRUE;//上锁
return old;
3.do{
、、、
while TS (&lock);先用TS指令测试lock
critical section;
lock=FALSE;
remainder section;
}while(TRUE);
4.利用Swap指令实现进程互斥
void swap(boolean *a,boolean *b){
boolean temp;
temp=*a;
*a=*b;
*b=temp;
do{
key=TRUE;
do{
swap(&lock,&key);
'''
}while(TRUE);
信号量机制
在介绍信号量之前,我先介绍一下什么是信号,大家在过马路的时候可能会遇到红绿灯,此时这个红绿灯就是相当于一个信号,有了这个信号,交通才能畅通无阻,多个路口有序进行,这相当于多个进程之间,有了信号量(相当于信号的集合)的管制,这个进程之间会有条不紊的进行下去。
整型信号量
wait(S){
while(S<=0); /*do no-op*/
S--;}
signal(S){
S++;
}
一般我们讨论记录型信号量
typedef struct{
int value;//代表资源数目
struct proccess_control_block *list;//pcb 进程数据结构 阻塞队列
}semaphore;
wait(semaphore *S){
S->value--;
if(S->value<0) block(S->list);
}
signal(semaphore *S){
S->value++;
if(S->value<=0) wakeup(S->list);
}
AND型信号量是指:将进程在整个运行过程中需要的所有资源,一次性全部地分配给进程,待进程使用完再一起释放
信号量集这里就不多赘述了。
信号量的应用
假设两个并发执行的进程P1和P2
P1有语句S1,P2有语句S2。
目标:要使S1执行后再执行S2
方法:使P1和P2共享一个初值为0的公用信号量S
P1中:执行S1:signal(S);
P2中:wait(S);在执行S2;
利用记录型信号量解决PC问题(生产者-消费者)
wait(P【测试】)
signal(V【释放】增加)
empty=buffer_size;//空闲缓冲区个数
full=0;
mutex=1;
Producer(item){
wait(empty);//判断空闲缓冲区的是否为空(0)
wait(mutex);//互斥,一次进来一个进程(上锁)
临界区(共享资源)
signal(mutex)
signal(full)}
Consumer(){
wait(full);
wait(mutex);
临界区(共享资源)
signal(mutex)
signal(empty)
}