⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 problem.c

📁 哲学家问题
💻 C
字号:
/*
要求:有5个哲学家坐在一个圆桌上,他们的生活方式是交替的进行思考和就餐。食物摆在桌子中间,桌子
      上总共有5把叉子,每个哲学家的左右手各有一把。因为吃饭时,哲学家需要同时使用左手和右手
      的叉子,所以哲学家必须和他左边和右边的哲学家共享叉子。在这个实验中,假定哲学家每次吃饭
      的时间长度为单位1,吃完一次后则放下两把叉子。如果等待10个单位时间长度之后,哲学家仍没有
      得到叉子吃饭,则被饿死。你需要设计一种方法使得任何一个哲学家都不被饿死。
 
有关内容:VxWorks信号量、定时器和消息队列的程序设计,并通过实验了解资源冲突的原因和解决方法。

*/

#include <vxWorks.h>
#include "taskLib.h"
#include "semLib.h"
#include "wdLib.h"
#include "sysLib.h"
#include "string.h"
#include <stdio.h>
#include "philosopher.h"

/* Define global variables */
#define taskBasePri	100   /*the base priority of task */
#define taskUrgentPri	99    /*the priority in some urgent situation */
#define NUM		5
#define WAITTIME	10
#define EATTIME		3
#define PERIOD		sysClkRateGet()


struct philosopher
{
	int status;           /*the status of philosopher,  0:thinking, 1:eating, 2:waiting  */
	int remanentTime;     /*the leftover time before philosoper have to eat */
};

int chopSticks[NUM+1];    /* the status of the chopsticks   0:free, 1:being used */
struct philosopher ph[NUM];	  /* create NUM phiosoper */
WDOG_ID wdog;
int taskId[NUM];

void systemInit(void)
{
	int i;
	/* initialization global variables*/
	for (i=0;i<NUM;i++)
	{
		chopSticks[i] = 0;
		ph[i].status = 0;
		ph[i].remanentTime = WAITTIME;
	}
	
	/* create watchDog */
	if ((wdog = wdCreate()) == NULL)
	{
		logMsg("systemInit: Create WatchDog failed!\n");
		return;
	}
	
	/* create tasks */	
		for (i=0;i<NUM;i++)
		{
			if ((taskId[i] = taskSpawn(NULL, taskBasePri, 0, 2000, (FUNCPTR)taskOfPh, i, 0,0,0,0,0,0,0,0,0)) == ERROR)
			{
				logMsg("systemInit: Error in taskSpawn!\n");
				return;
			}
		}	
	
	/* start WatchDog*/
	if (wdStart(wdog, PERIOD, (FUNCPTR)monitor, 0) == ERROR)
	{
		logMsg("systemInit: Start WatchDog Error!\n");
		return;
	}	

	kernelTimeSlice(PERIOD/100);  /*   task slice*/
	 	
	printf("systemInit: System initialization finished!\n");
}

/* the entrance of Philosoper task */
void taskOfPh(int i)
{
	while(1)
	{
		if (i >= NUM)
		{
			logMsg("taskOfPh: Param Error!");
			return;
		}
		/* still alive? */
		if (ph[i].remanentTime < 0)
			break;
			
		/*if remanentTime is less than EATTIME, should wait to eat*/
		if (ph[i].remanentTime < EATTIME)
		{
			ph[i].status = 2;
		
			/* if the chopsticks is free,than start to eat*/
			if (chopSticks[i] == 0 && chopSticks[i+1] == 0)
			{
				taskLock();
				chopSticks[i]= 1;
				chopSticks[i+1] = 1;
				chopSticks[0] = chopSticks[NUM];  /* make 0 and NUM point to the same value */
				ph[i].status = 1;
				taskUnlock();
				taskDelay(PERIOD);
				ph[i].remanentTime = 10;
				chopSticks[i]= 0;
				chopSticks[i+1] = 0;
				chopSticks[0] = chopSticks[NUM];  /* make 0 and NUM point to the same value */
				ph[i].status = 0;
				taskPrioritySet(taskIdSelf(),taskBasePri);  /* setback the priority */
			}
			else
				taskDelay(PERIOD/10);
		}
	}
	
}

/* monitor for the tasks, executed by watchDog */
void monitor(void)
{
	int i;
	char taskName[5];
	char t[] = "123";
	
	/* make this function executed every PERIOD */
	if (wdStart(wdog, PERIOD, (FUNCPTR)monitor, 0) == ERROR)
	{
		logMsg("systemInit: Start WatchDog Error!\n");
		return;
	}
	
	/* monitor for every task */
	for (i=0; i<NUM; i++)
	{
		ph[i].remanentTime--;
		if (ph[i].remanentTime < 0)
		{
			printf("monitor: Philosopher %d is dead!\n", i+1);
			continue;
		}
		/*urgent situation */
		if (ph[i].remanentTime < EATTIME)
		{
			taskPrioritySet(taskId[i],taskUrgentPri);
		}
		
		/* philosophers status shift */
		if (ph[i].status == 1)
		{
			ph[i].status = 0;
			ph[i].remanentTime = 10;
		}
		switch(ph[i].status)
		{
		case 0:
			printf("Philosopher %i is thinking...(%d)\n", i+1,ph[i].remanentTime);
			break;
		case 1:
			printf("Philosopher %i is eating...\n", i+1);	
			break;
		case 2:
			printf("Philosopher %i is waiting to eat\n.", i+1);
			break;
		default:
			logMsg("taskOfPh: Status Error!\n");
			ph[i].status = 0;
			break;
		}
		
	}
	printf("-----------------\n");

}

/* function for system exit */
void systemExit(void)
{
	int i;
	/*cancel and delete WatchDog*/
	if (wdCancel(wdog) == ERROR)
	{
		logMsg("systemExit: Cancel watchDog Failed!\n");
		return;
	}
	if (wdDelete(wdog) == ERROR)
	{
		logMsg("systemExit: Delete watchDog failed!\n");
		return;
	}
	
	/*detele all task*/
	for (i=0; i<NUM; i++)
		if (taskDelete(taskId[i]) == ERROR)
		{
			logMsg("systemExit: Task delete failed!\n");
			return;
		}
	
	printf("systemExit: System Exit OK!\n");	
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -