Linux c 实现哲学家吃饭问题(多线程版)

哲学家进餐

五个哲学家在一个桌子上就餐,只有五只筷子,一碗面,只有同时拿到了两根筷子才可以开始进餐,如何让这五个哲学家吃到饭。

思路

哲学家的问题也是一个死锁的问题,在计算机中代表当多个进程开始请求资源时,在多个进程之间分配多个资源,而且不会出现死锁和饥饿。

一种简单的方法是哲学家门统一思想,分左右手,所有的哲学家优先选取左手的筷子,如果抢到了左手的筷子但没有抢到右手的筷子,就把左手的筷子也放回去。但是这样很可能会发生死锁,因为都优先选取左手实际上还是每人一根筷子。这个时候就需要一个搅局者,(搅局者E)一个人先去抢右手的筷子。如这样必有一个人(哲学家D或搅局者E)抢不到筷子。从而放弃自己的已得的筷子,成全别人。
A线程 优先掌握锁1和 锁5
B线程 优先掌握锁2和 锁1
C线程 优先掌握锁3和 锁2
D线程 优先掌握锁4和 锁3
E线程 优先掌握锁4和 锁5

(下图中黑色为左手,白色为右手)
在这里插入图片描述

代码

#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <stdlib.h>

//互斥锁
pthread_mutex_t lock[5];

//线程
void *thr(void *arg)
{
	int left, right;

	int i = (int)arg;

	// 前四个抢左手
	if (i < 4)
	{
		left = i;
		if (i == 0)
		{
			right = 4;
		}
		else{
			right = i - 1;
		}
	}

	//第五个抢右手lock
	if (i == 4)
	{
		left = i-1;
		right = i;
	}
	while (1)
	{

		//申请左边的锁
		pthread_mutex_lock(&lock[left]);

		//申请右边的锁
		if ((pthread_mutex_trylock(&lock[right])) != 0)
		{
			pthread_mutex_unlock(&lock[left]);
			printf(" ==线程 %d ==  申请失败\n", i);
			continue;
		}

		//左右都申请成功
		printf("==线程 %d == succesful\n", i);

		//释放锁
		pthread_mutex_unlock(&lock[left]);
		pthread_mutex_unlock(&lock[right]);

		sleep(1);
	}
}

int main()
{
	//初始化
	for (int i; i < 5; i++)
	{
		pthread_mutex_init(&lock[i], NULL);
	}

	//创建线程
	pthread_t dit[5];
	for (int i = 0; i < 5; i++)
	{
		pthread_create(&dit[i], NULL, thr, (void *)i);
	}

	//回收线程
	for (int i = 0; i < 5; i++)
	{
		pthread_join(dit[i], NULL);
	}
	//销毁
	pthread_exit(NULL);

	return 0;
}
Logo

更多推荐