进程同步的三个经典问题

版权声明:醋姑娘 https://blog.csdn.net/weixin_37023469/article/details/84501362

1. 有限缓存问题 Bounded-Buffer Problem

要求:

  1. producer和consumer,二者不能对buffer进行操作
  2. 当buffer满的时候,就不允许producer继续写
  3. 当buffer空的时候,就不允许consumer继续读

信号量及其初始化

Semaphore mutex = 1; //buffer的锁
Semapore full = 0; //满位的数量
Semaphore empty = n; //空位的数量

producer简单代码描述

/*PV形式*/
while(true){
	P(empty);
	P(mutex);
	//write...
	V(mutex);
	V(full);
}

/*wait signal形式*/
while(true){
	wait(empty);
	wait(mutex);
	//write...
	signal(mutex);
	signal(full);
}

consumer简单代码描述

/*PV形式*/
while(true){
	P(full);
	P(mutex);
	//read...
	V(mutex);
	V(empty);
}

/*wait signal形式*/
while(true){
	wait(full);
	wait(mutex);
	//read...
	signal(mutex);
	signal(empty);
}

分析:
具有对称性
先申请empty/full位,再申请缓冲区访问权限;先释放mutex再释放empty/full位

2. 读者写者问题 Readers and Writers Problem

要求:

  1. 多个读者,只能read,不能write
  2. 多个写者,既能read,也能write
  3. 允许多个reader同时读
  4. 不允许reader和writer同时操作
  5. 不允许多个写者同时操作

本质:保证一个writer进程必须与其他进程互斥地访问共享对象

情况零:弱写者优先(公平竞争)

要求:?
太简单了(以后再补)

情况一:读者优先

要求:

  1. 有读者在读,则其他读者可读,直到没有读者了,写者才能写
  2. 有写者在写,则其余写者和读者等待

信号量及其初始化

int readercount = 0;//共享变量,记录当前读者的数量
Semaphore mutex = 1;//readercount的锁
Semaphore m = 1;//buffer的锁

writer简单代码描述

while(true){
	wait(m);

	//write

	signal(m);
}

reader简单代码描述

while(true){
	wait(mutex);
	readercount++;
	if(readercount==1){
		wait(m);
	}
	signal(mutex);

	//read

	wait(mutex);
	readercount--;
	if(readercount==0){
		signal(m);
	}
	signal(mutex);
}

情况二:强写者优先

要求:

  1. 写者在写,则其余读者和写者等待;写者写完,优先释放下一个写者
  2. 读者在读,若无写者等待,则其他读者可读
  3. 读者在读,若有写者等待,则其他读者等待

信号量及其初始化

int readercount = 0;//共享变量,记录当前读者的数量
int writecount = 0;//共享变量,记录当前写者的数量

Semaphore mutex1 = 1;//readercount的锁
Semaphore mutex2 = 1;//writecount的锁

Semaphore read = 1;//buffer的读锁
semaphore write = 1;//buffer的写锁

Semaphore s = 1;//为了让写者优先

writer简单代码实现

while(true){
	
	wait(mutex2);
	writecount++;
	if(writecount==1){
		wait(read);
	}
	signal(mutex2);

	wait(write);
	//write...
	signal(write);

	wait(mutex2);
	writecount--;
	if(writecount==0){
		signal(read);
	}
	signal(mutex2);

}

reader简单代码实现

while(true){

	wait(s);
	wait(read);
	readercount++;
	if(readercount==1){
		wait(write);
	}
	signal(read);
	signal(s);

	//reading..

	wait(mutex1);
	readercount--;
	if(readcounter==0){
		signal(write);
	}
	signal(mutex1);

}

3.哲学家进餐问题 Dining-Philosophers Problem

要求:

  1. 有5个哲学家
  2. 哲学家只能吃饭或者思考,不能同时进行
  3. 哲学家只能拿两根筷子才能吃饭

方案一:最多只允许4个哲学家同时坐在桌子上

Semaphore chopstick[5]={1,1,1,1,1};//筷子是否可用
Semaphore seat=4;//可坐的位置

void philosppher(int i){
	
	while(true){
		
		think();
		
		wait(seat);//申请座位

		wait(chopstick[i]);
		wait(chopstick[(i+1)%5]);
		eat();
		signal(chopstick[(i+1)%5]);
		signal(chopstick[i]);

		signal(seat);

	}
}

方案二:非对称方法,奇数哲学家拿左边的筷子,偶数哲学家拿右边的筷子

Semaphore chopstick[5]={1,1,1,1,1};//筷子是否可用

void philosppher(int i){

	while(true){
		think();

		if(i&1){
			wait(chopstick[i]);
			wait(chopstick[(i+1)%5]);
			eat();
			signal(chopstick[(i+1)%5]);
			signal(chopstick[i]);			
		}
		else{
			wait(chopstick[(i+1)%5]);
			wait(chopstick[i]);
			eat();
			signal(chopstick[i]);	
			signal(chopstick[(i+1)%5]);
		}
	}
}

方案三:只有当两边都有筷子的时候才会同时拿起两只筷子

借助AND型信号量,其基本思想是:将进程在整个运行过程中需要的所有资源一次性全部分配给进程,待进程使用完后再一起释放。只要尚有一个资源未能分配给进程,其他所有可能为之分配的资源也不分配给它。

Semaphore chopstick[5]={1,1,1,1,1};//筷子是否可用

void philosppher(int i){

	while(true){
		
		think();

		Swait(chopstick[i],chopstick[(i+1)%5]);
		eat();
		Ssignal(chopstick[i],chopstick[(i+1)%5]);
	}
}

猜你喜欢

转载自blog.csdn.net/weixin_37023469/article/details/84501362