哲学家就餐问题代码

// Test.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>
using namespace std;

#define LEFT(n)  ((n+4)%5)
#define RIGHT(n) ((n+1)%5)

class MySemaphore
{
public:
	MySemaphore::MySemaphore(long nInitCount)
	{
		m_sem = CreateSemaphore(NULL,nInitCount,MAXLONG32,NULL);
	}

	bool down(DWORD dwMilliseconds)
	{
		if (m_sem)
		{
			DWORD dwRet = WaitForSingleObject(m_sem,dwMilliseconds);

			if (WAIT_OBJECT_0 == dwRet)
			{
				return true;
			}
		}

		return false;
	}

	bool up()
	{
		if (m_sem)
		{
			return ReleaseSemaphore(m_sem,1,NULL) ? true : false;
		}

		return false;
	}
private:
	HANDLE m_sem;
};

enum PersonState
{
	STATE_THINKING,
	STATE_WAITING,
	STATE_EATING,
};

MySemaphore personArr[5] = {0,0,0,0,0};
PersonState  stateArr[5] = {STATE_THINKING,STATE_THINKING,STATE_THINKING,STATE_THINKING,STATE_THINKING};
MySemaphore mutex = 1;

void test(int nIndex)
{
	if (stateArr[nIndex] == STATE_WAITING &&
		stateArr[LEFT(nIndex)] != STATE_EATING&&
		stateArr[RIGHT(nIndex)] != STATE_EATING)
	{
		stateArr[nIndex] = STATE_EATING;
		personArr[nIndex].up();
	}
}

void take_fork(int nIndex)
{
	mutex.down(INFINITE);
	stateArr[nIndex] = STATE_WAITING;
	test(nIndex);
	mutex.up();

	personArr[nIndex].down(INFINITE);
}

void put_fork(int nIndex)
{
	mutex.down(INFINITE);
	stateArr[nIndex] = STATE_THINKING;
	printf("person %d put fork and thinking\n",nIndex+1);
	test(LEFT(nIndex));
	test(RIGHT(nIndex));
	mutex.up();
}

DWORD WINAPI PersonProc( LPVOID lpParam )
{
	int nThreadIndex = (int)lpParam;

	for(;;)
	{
		take_fork(nThreadIndex);
		printf("person %d take fork and eating\n",nThreadIndex+1);
		Sleep(1000); //eating;
		put_fork(nThreadIndex);
	}

	return 0;
}

int _tmain(int argc, _TCHAR* argv[])
{
	HANDLE aThread[5];

	for(int i=0; i < 5; i++ )
	{
		aThread[i] = CreateThread(
			NULL,       // default security attributes
			0,          // default stack size
			(LPTHREAD_START_ROUTINE) PersonProc,
			(void*)i,       // no thread function arguments
			0,          // default creation flags
			NULL); // receive thread identifier

		if( aThread[i] == NULL )
		{
			printf("CreateThread error: %d\n", GetLastError());
			return 1;
		}
	}

	Sleep(-1);
	return 0;
}

具体分析参考<现代操作系统>相关章节

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-11-03 22:22:15

哲学家就餐问题代码的相关文章

JAVA并发,经典死锁案例-哲学家就餐

转自:http://blog.csdn.net/tayanxunhua/article/details/38691005 死锁经典案例:哲学家就餐. 这个案例会导致死锁. 通过修改<Java编程思想4>一书中的案例,来做实验,代码更易理解,结果也相对容易控制. 附代码: 筷子类: 1 package com.tyxh.ch21.c6; 2 3 public class Chopstick { 4 private boolean taken = false;//判断是此筷子是否被拿起 5 pub

Thking in Java---从哲学家就餐问题看死锁现象

我们知道一个对象可以有synchronized方法或其他形式的加锁机制来防止别的线程在互斥还没释放的时候就访问这个对象.而且我们知道线程是会变成阻塞状态的(挂起),所以有时候就会发生死锁的情况:某个任务在等待另一个任务,而后者又在等待其它任务,这样一直下去,知道这个链条下的任务又在等待第一个任务释放锁,这样就形成了一个任务之间相互等待的连续循环,没有任务可以继续的情况.死锁的最大问题在于它发生的几率非常小,并不是我们一运行程序它就死锁了,而是会不知道那个时候程序就死锁了并且我们很难重现当时出现死

从哲学家就餐问题彻底认识死锁

第一节  哲学家就餐问题 第二节  什么是死锁 第三节  死锁的定义 第四节  死锁发生的条件 第五节  如何避免死锁 5.1 动态避免,银行家算法(杠杆分配),在资源分配上下文章 5.2 静态避免,从任务代码上避免死锁 第六节  死锁的综合治理 第一节  哲学家就餐问题 假设有五位哲学家围坐在一张圆形餐桌旁,做以下两件事情之一:吃饭,或者思考.吃东西的时候,他们就停止思考,思考的时候也停止吃东西.餐桌中间有一大碗意大利面,每两个哲学家之间有一双筷子.因为用一只筷子很难吃到意大利面,所以假设哲学

IPC问题-哲学家就餐

如上图,有五位哲学家,盘中的食物只有左右两个叉子都拿起才能吃.哲学家在桌上只有思考(等待)和吃面(执行).看起来最多是只有2个人能同时吃. 版本一:这个思路的最糟糕的就是都拿起左边叉子,那样都没法吃了,直接死锁. 版本二:改进版本一,如果拿起左边叉子,先看右边是否能用,不可用的话放下左边叉子等待一段时间再运行.这个思路的问题就是,会产生某个时刻每个人都拿起左叉子,又放下,又拿起,虽然没有死锁,但是没有人在吃面,消耗了性能但是任务没有进展,造成饥饿. 版本三:改进版本二,每次等待右边是否能用的每个

线程学习五:哲学家就餐问题

问题描述: 设有5个哲学家,共享一张放有5把椅子的桌子,每人分得一把椅子,但是,桌子上共有5只筷子,在每人两边各放一只,哲学家们在肚子饥饿时才试图分两次从两边拿起筷子就餐. 条件: 1)拿到两只筷子时哲学家才开始吃饭. 2)如果筷子已在他人手上,则该哲学家必须等他人吃完之后才能拿到筷子. 3)任一哲学家在自己未拿到两只筷子前却不放下自己手中的筷子. 解题思路: 如果哲学家身边的2把筷子都没人使用,哲学家便可以就餐,否者哲学家只能等待别人就餐完毕.那么就根据哲学家身边的筷子状态做判断,满足条件便就

Java多线程,哲学家就餐问题

问题描述:一圆桌前坐着5位哲学家,两个人中间有一只筷子,桌子中央有面条.哲学家思考问题,当饿了的时候拿起左右两只筷子吃饭,必须拿到两只筷子才能吃饭.上述问题会产生死锁的情况,当5个哲学家都拿起自己右手边的筷子,准备拿左手边的筷子时产生死锁现象. 解决办法: 1.添加一个服务生,只有当经过服务生同意之后才能拿筷子,服务生负责避免死锁发生. 2.每个哲学家必须确定自己左右手的筷子都可用的时候,才能同时拿起两只筷子进餐,吃完之后同时放下两只筷子. 3.规定每个哲学家拿筷子时必须拿序号小的那只,这样最后

哲学家就餐问题

1. 使用PV信号量使就餐互斥方案的缺点 将就餐看成必须互斥访问的临界资源, 这样会造成资源(叉子)的浪费.五把叉子, 一次应该有两个不相邻的哲学家同时进餐. 2. 算法实现 数据结构 1 #define N 5 // 哲学家个数 2 #define LEFT i-1 // 第i个哲学家的左邻居 3 #define RIGHT (i+1)%N // 第i个哲学家的右邻居 4 #define THINKING 0 // 思考状态 5 #define HUNGRY 1 // 饥饿状态 6 #defi

哲学家就餐

#include <stdio.h>#include <stdlib.h>#include <memory.h>#include <pthread.h>#include <errno.h>#include <math.h>//筷子作为mutexpthread_mutex_t chopstick[6] ;void *eat_think(void *arg){    char phi = *(char *)arg;    int left

IPC----哲学家就餐问题(并发与互斥)

哲学家就餐问题描述: 5个哲学家,5个筷子.5个哲学家围坐在一张桌子上,筷子放在分别放在每个哲学家的两旁.如果所有哲学家在某个时刻同时拿起左边的筷子,那么右边的筷子就都被其他的哲学家拿了,造成大家都无法吃饭.但是大家都不想放下左边的筷子(规则是先拿起左边筷子在拿起右边的,吃完饭在放下两个筷子),这就是死锁. 解决这个问题有个办法是 在拿起筷子前先判断左右两个筷子是否可用,可用才能拿,而且是同时拿,这样不相邻的哲学家就可以吃上饭,不会造成死锁. 实现代码如下 #include <sys/types