【线程同步三部曲】之哲学家进餐问题,c语言实现

本文介绍了哲学家进餐问题的背景和约束条件,并提出了两个C语言实现方案:一个简单但可能导致死锁的方案,以及一个通过‘单双号限流’避免死锁的改进方案。通过对线程单双号的控制,确保了哲学家能正确获取筷子并避免死锁的发生。
摘要由CSDN通过智能技术生成

问题描述

背景描述
有五个哲学家,他们的生活方式是交替地进行思考和进餐,哲学家们共用一张圆桌,分别坐在周围的五张椅子上,在圆桌上有五个碗和五支筷子,平时哲学家进行思考,饥饿时便试图取其左、右最靠近他的筷子,只有在他拿到两支筷子时才能进餐,该哲学家进餐完毕后,放下左右两只筷子又继续思考。
在这里插入图片描述

约束条件:
(1)只有拿到两只筷子时,哲学家才能吃饭。
(2)如果筷子已被别人拿走,则必须等别人吃完之后才能拿到筷子。
(3)任一哲学家在自己未拿到两只筷子吃完饭前,不会放下手中已经拿到的筷子。

解决方案

我们要实现的是每个哲学家都有机会拿到左右两把叉子进行用餐,那么,可以明确的是叉子成为相邻哲学家进餐的竞争条件。接下来,我们通过一些操作实现哲学家间取叉子的同步而不产生死锁。

一、一个最简单但不安全的方案

方案描述

在这里插入图片描述

如上图,对所有哲学家和叉子进行编号,每个哲学家右手的叉子的编号与哲学家编号相同。进餐时,每个哲学家先取得右手的叉子,再取得左手的叉子,方可开始进餐。

下图是对上述方案的流程描述
在这里插入图片描述
到这,不妨思考几秒钟,这个方案会产生什么问题呢?
在这里插入图片描述
好了,揭晓漏洞:
这种实现是有可能产生死锁的,即所有哲学家都拿着右手边的叉子,都在等待左手边的叉子,于是每个人都干等着,谁都吃不到饭。

方案代码
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
#include <sys/types.h> 


#define NUM 5

int eaters = 0;

//-------------------一些信号量----------------
sem_t sem_fork[NUM];
sem_t sem_eaters;
void sem_mutex_init()
{
   
	int i;
	for(i = 0;i < NUM; ++i)
		if(sem_init(&sem_fork[i],0,1) == -1)
		{
   
			printf("sem_init失败,退出!\n");
			exit(1);
		}
	if(sem_init(&sem_eaters,0,1) == -1)
	{
   
		printf("sem_init失败,退出!\n");
		exit(1);
	}
	return ;
}

void philosopher()
{
   
	for(
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值