【OS】Semaphore & Synchronization Issues

理发师睡觉问题.

//理发店由等待间(包含N个等待座位)和理发间(包含一把理发椅)
//构成。无顾客时,理发师睡觉;当顾客进入理发店发现理发师睡
//觉时,则唤醒理发师。

const int seat=N;		//表示N个等待座位

//信号量设置如下:
semaphore customer=0;
semaphore mutex=1;
semaphore CutSeat=1;

int Waiting=0;

Barber()
{
    
    
	while(true)
	{
    
    
		wait(customer);		//理发师查看有无顾客
		wait(mutex);		//保证对于Waiting变量的互斥访问
		Waiting--;
		signal(mutex);
		
		CuttingHair();		//开始理发
		signal(CutSeat);	//释放理发位
	}
}

Customer()
{
    
    
	while(true)
	{
    
    
		wait(mutex);			//保证对Waiting的互斥访问
		if(Waiting<seat)		//判断是否还有座位
		{
    
    
			Waiting++;		
			signal(mutex);
			signal(customer);	//增加顾客信号量
			wait(CutSeat);		//申请理发位
			GoToCutSeat();		//前往理发
		}
		else
		{
    
    
			signal(mutex);		//座位已满,离开
		}
	}
}

喂金鱼问题.

//假设张三和李四共同养一条金鱼,金鱼每天进食一顿,
//所以每天仅且只能喂一次,若超过一次,金鱼胀死,
//若一次都没有喂,金鱼饿死两人都想把金鱼养活,请给
//两人设置喂养金鱼的方式,并用伪代码描述两人行为

//信号量设置如下:
semaphore mutex=1; 			//保证对于Times的互斥访问

int Times=0;

Three()
{
    
    
	while(true)
	{
    
    
		wait(mutex);		//申请访问Times
		if(Times<1)
		{
    
    
			Feeding();		//没喂,就喂
			Times=1;
			signal(mutex);
		}
		else
		{
    
    
			signal(mutex);	//喂了,很好
		}
	}
}

//Four()行为一致
Four(){
    
    }

第一读者-写者问题.

//共享的数据集或文件可能在多个进程间被并发访问,因此
//可能有多个读者和写者对其进行操作,一般要求多个读者
//可以同时操作,而读者与写者、多个写者之间的操作应互斥。
//第一读写问题中,读者不会等待,除非写者已经获得了共享
//资源的使用权,这一问题会导致写者饿死。

//信号量设置如下:
semaphore priority=1;	//代表读者优先级高于写者
semaphore mutex=1;		//互斥访问count

int count=0;

Reader()
{
    
    
	while(true)
	{
    
    
		wait(mutex);
		count++;
		if(count==1)
		{
    
    
			wait(priority);	//首位Reader需要确定没有Writer
		}
		signal(mutex);
		Reading();
		wait(mutex);
		count--;
		if(count==0)
		{
    
    
			signal(priority);//最后一个Reader需要释放写权限
		}
		signal(mutex);
	}
}

Writer()
{
    
    
	wait(priority);
	Writing();
	signal(priority);
}

//存在写者饿死的情况,因为读者进程会计数持续占有priority
//所以只要当前有读者在运行,陆续还有新的读者加入,写者就无法
//获得priority.

第二读者-写者问题.

//针对第一读写问题中的写者饿死状况,第二读写问题中要求
//一旦作者准备就绪,那么作者会尽可能快地执行,换句话说
//如果有一个作者申请访问对象并且正在等待,就不会有新的
//读者能够成功访问共享资源。

//信号量设置如下:
semaphore file=1;		//代表共享资源
semaphore priority=1;	//代表写者进程优先级高于读者进程

//互斥信号量:
semaphore mutex_W=1;
semaphore mutex_R=1

int Writer=0;
int Reader=0;

Writer()
{
    
    
	while(true)
	{
    
    
		wait(mutex_W);
		Writer++;
		if(Writer==1)
		{
    
    
			wait(priority);	//第一个写者需要申请优先级信号量
		}
		signal(mutex_W);
		
		wait(file);
		Writing();
		signal(file);

		wait(mutex_W);
		Writer--;
		if(Writer==0)
		{
    
    
			signal(priority);//最后一个写者释放优先级信号量
		}
		signal(mutex_W);
	}
}

Reader()
{
    
    
	while(true)
	{
    
    
		wait(priority);	//如果此时有写者正在写或等待
						//Reader都无法获得priority
		wait(mutex_R);
		Reader++;
		if(Reader==1)
		{
    
    
			wait(file);	//第一个读者申请共享资源
		}
		signal(mutex_R);
		signal(priority);

		Reading();

		wait(mutex_R);
		Reader--;
		if(Reader==0)
		{
    
    
			signal(file);
		}
		signal(mutex_R);
	}
}

//存在的问题是读者饿死,因为写者会计数持续占有priority,直到
//最后一个写者进程退出之前,第一个读者永远无法获得priority,
//也就更无法获得file.

读写公平问题.

//1.优先级相同。
//2.写者、读者互斥访问。
//3.只能有一个写者访问临界区。
//4.可以有多个读者同时访问临界资源。

//信号量设置如下:
semaphore file=1;
semaphore priority=1;	
//读-写的互斥访问以及写-写互斥,命名出于和第二问题的代码对应

semaphore read=1; 		
//读者之间互斥访问Reader

int Reader=0;

Writer()
{
    
    
	wait(priority);	
	wait(file);
	signal(priority);

	Writing();

	signal(file);
}

Reader()
{
    
    
	
	wait(priority);
	wait(read);
	Reader++;
	if(Reader==1)
	{
    
    
		wait(file);
	}
	signal(read);
	signal(priority);

	reading();
	
	wait(read);
	Reader--;
	if(Reader==0)
	{
    
    
		signal(file);
	}
	signal(read);
}

//注意读写进程都会在自己成功获得file后释放priority,而不是
//上面两种解法中存在一方的持续占有,直到本类型进程为0,这样
//就实现了公平竞争。
  • 有关读者写者问题,可以参看这篇文章以相互印证。

哲学家就餐问题.

在这里插入图片描述

//1.假设有5个哲学家,所有的时间用来吃饭和思考,他们共
//坐一个圆桌上,每个人坐一把椅子,桌上有5根筷子
//2.当某位哲学家感到饥饿时,他会试图拿桌上的筷子,每次
//只能拿一根,当同时有一双筷子时,他可以吃饭,吃饱后会
//放下两根筷子,开始思考
//3.需要在多个进程之间分配多个资源且不会出现死锁和饿死

//信号量设置如下:
semaphore chopsticks[5]=1;
semaphore mutex=1;

int number=0;

Philosopher_i()
{
    
    
	while(true)
	{
    
    
		wait(mutex);
		number++;
		if(number<=4)
		{
    
    
			wait(chopsticks[i]);
			wait(chopsticks[(i+1)%5]);
		}
		signal(mutex);

		Eating();
		
		wait(mutex);
		number--;
		signal(chopsticks[i]);
		signal(chopsticks[(i+1)%5])
		signal(mutex);

		Thinking();
	}
}

//可以看出这里的解决方法是,设定变量number,使得最多有4位哲学家
//上桌吃饭,4个进程5个资源,总有一个哲学家能够吃饭,从而不会造
//成死锁。

//其他的解决方法还有:
//1.只有两根筷子同时可用时,才允许哲学家拿筷子;
//2.奇数哲学家先拿左手边的筷子,偶数哲学家先拿起右手边的筷子.
  • 有关哲学家问题,可以参看这篇文章了解更多。

猜你喜欢

转载自blog.csdn.net/weixin_44246009/article/details/108533661
今日推荐