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

📄 test.c

📁 TC-ucos-philos-详细注释.rar 用TC编译ucos并在图像化界面下演示哲学家就餐问题
💻 C
字号:
/*this code is a demo of dining pholospher problem in UCOS-II
copyright Zengzhi Wang 2008.6.11
note:compile and run in TC3.0 with Graphics Functions on
*/
#include <GRAPHICS.H>
#include <MATH.H>
#include "includes.h"


#define pi 3.141592653
#define CenterX 400							/*桌子的圆心坐标*/
#define CenterY 250
#define r 100								/*桌子的半径*/

#define  TASK_STK_SIZE   512				//任务堆栈长度

OS_STK   StartTaskStk[TASK_STK_SIZE];		//定义任务堆栈区
OS_STK	 PhilosStk[5][TASK_STK_SIZE];
INT8U	 PhilosID[]={1,2,3,4,5};			/*哲学家编号1-5*/	
OS_FLAGS ChopGrp[]={3,6,12,24,17};			/*每个哲学家申请的筷子标志位,用移位方法亦可*/

INT16S   key;								//用于退出uCOS_II的键	

INT8U   err;								/*存储错误信息*/
INT8U	x=0,y=0,z=0;						//字符显示位置
INT8U	i=0;								/*计数器*/

int driver=0,mode=0;						/*显示驱动和模式 CGA*/
int philosx[5],philosy[5];					/*哲学家坐标*/
int x1[5],y1[5];							/*筷子外端坐标*/
int x2[5],y2[5];							/*筷子里端坐标*/

OS_FLAG_GRP *WFlag;							/*筷子的事件标志组*/
OS_FLAGS Chops=31;							/*标志组初始值,所有筷子有效*/

void  StartTask(void *data);				/*初始化任务,运行完毕后将自己挂起*/
void  Philos(void *data);					/*哲学家进程,5个均相同*/
void  PickChop(INT8U id);					/*拿起筷子-画黑线将白线覆盖*/
void  PutChop(INT8U id);					/*放下筷子-画白线再次显示筷子*/
void  Thinking(INT8U id);					/*覆盖原来的图形(Eating),再次画圆*/
void  Hungry(INT8U id);						/*将圆填充为Wide_DOT模式*/
void  Eating(INT8U id);						/*将圆填充为实心*/
void  Quitkey(void);						/*检测退出*/

/************************主函数*********************************************/
void  main (void)
{
    OSInit();								//初始化uCOS_II
    PC_DOSSaveReturn();						//保存Dos环境
    PC_VectSet(uCOS, OSCtxSw);				//安装uCOS_II中断
	/*哲学家坐标和筷子坐标初始化计算*/
	for(i=0;i<5;i++)						
	{
		philosx[i]=(int)(CenterX+r*sin(pi*(72*i)/180));
		philosy[i]=(int)(CenterY-r*cos(pi*(72*i)/180));
		x1[i]=(int)(CenterX+(r+20)*sin(pi*(72*i-36)/180));
    	y1[i]=(int)(CenterY-(r+20)*cos(pi*(72*i-36)/180));
		x2[i]=(int)(CenterX+(r-20)*sin(pi*(72*i-36)/180));
    	y2[i]=(int)(CenterY-(r-20)*cos(pi*(72*i-36)/180));
	}

	WFlag=OSFlagCreate((OS_FLAGS)31,&err);		/*创建事件标志组并检验是否创建成功*/
	if(err==OS_NO_ERR)
		PC_DispStr(20,24,"Flag create no error",DISP_BGND_BLACK+DISP_FGND_YELLOW);
    OSTaskCreate(StartTask,0,&StartTaskStk[TASK_STK_SIZE - 1],5);		
    OSStart();			
}
/************************************************************************************
哲学家及筷子显示算法:

			 O

  O                    O

        O        O
每两个哲学家之间的夹角为72度,
取圆心到每个哲学家半径和圆心到第一个(最上面的)哲学家的半径之间的夹角计算每个哲学家的位置
筷子的位置其实是哲学家逆时针旋转36度的位置。
哲学家在坐标处画圆即可
筷子头尾坐标分别是一个围着大桌的哲学家逆时针36度,和一个小桌的哲学家逆时针36度的结果
*/
//*****************************StartTask********************************************
void  StartTask(void *pdata)
{
	char temp[50];
	pdata=pdata;
    OS_ENTER_CRITICAL();
    PC_VectSet(0x08, OSTickISR);
    PC_SetTickRate(OS_TICKS_PER_SEC);
    OS_EXIT_CRITICAL();
//  OSStatInit();
	/*创建哲学家进程并检测*/
	for(i=0;i<5;i++)
	{
		err=OSTaskCreate(Philos,(void *)&PhilosID[i],&PhilosStk[i][TASK_STK_SIZE - 1],i+6);
//需用OutText显示
//		if(err==OS_NO_ERR)
//			//test if task is created successfully
//		{
//			sprintf(temp,"Philosopher %d create error",PhilosID[i]);
//			PC_DispStr(0,20+i,temp,DISP_BGND_BLACK+DISP_FGND_YELLOW);
//			sprintf(temp,"%d",err);
//        		PC_DispStr(30,20+i,temp,DISP_BGND_BLACK+DISP_FGND_WHITE);
//		}

	}
	initgraph(&driver,&mode,"d:\\TCPP30E\\BGI");	/*初始化图形模式*/
	/*显示标题*/
	setcolor(YELLOW);
	outtextxy(150,30,"Demo of Dining Philosphy in Ucos-II");
	outtextxy(190,40,"by Zengzhi Wang 2008.6.10");
	/*demo of 三种状态*/
	setcolor(WHITE);
	outtextxy(20,80,"Thinking...");
	circle(120,85,10);
	/**/
	outtextxy(20,110,"Hungry...");
	circle(120,115,10);
	setfillstyle(WIDE_DOT_FILL,WHITE);
	floodfill(120,115,WHITE);
	/**/
	outtextxy(20,140,"Eating...");
	circle(120,145,10);
	setfillstyle(SOLID_FILL,WHITE);
	floodfill(120,145,WHITE);
	/*图像显示初始化,所有哲学家思考状态,筷子全部有效*/
	for(i=0;i<5;i++)
	{
		circle(philosx[i],philosy[i],20);
		line(x1[i],y1[i],x2[i],y2[i]);
	}
	OSTimeDly(1000);		 /*延时防止程序进入后马上开始吃而看不到效果*/
	OSTaskSuspend(OS_PRIO_SELF);	
}
//*****************************Philos********************************************
//the Philosopher first has to pick up the chopstick on his left hand then right
void  Philos(void *pdata)
{
	INT8U PhID;
	char temp[50];
   	PhID = *(INT8U *)pdata;		/*读取哲学家编号*/

    for (;;) 
	{
		Quitkey();
		/*哲学家开始Hungry*/
		Hungry(PhID-1);
		OSTimeDly(400);
		/*申请筷子并开始吃*/
		OSFlagPend(WFlag,ChopGrp[PhID-1], OS_FLAG_WAIT_SET_ALL + OS_FLAG_CONSUME,0,&err);
		PickChop(PhID-1);	/*拿右筷子*/
		PickChop(PhID%5);	/*拿左筷子*/
		Eating(PhID-1);
		OSTimeDly(400);
		/*吃完放筷子继续思考*/
		PutChop(PhID%5);
		PutChop(PhID-1);
		Thinking(PhID-1);
		OSFlagPost(WFlag,ChopGrp[PhID-1],OS_FLAG_SET,&err);
		/**/
		OSTimeDly(400);
       	Quitkey();

        }
}
//***************************PickChop()********************************************
void PickChop(INT8U id)
{
	setcolor(BLACK);
	line(x1[id],y1[id],x2[id],y2[id]);
}
//***************************PutChop()********************************************
void PutChop(INT8U id)
{
	setcolor(WHITE);
	line(x1[id],y1[id],x2[id],y2[id]);
}

//***************************Thinking()********************************************
void Thinking(INT8U id)
{
	setfillstyle(SOLID_FILL,BLACK);
	floodfill(philosx[id],philosy[id],BLACK);
	setcolor(WHITE);
	circle(philosx[id],philosy[id],20);
}
//***************************Hungry()********************************************
void Hungry(INT8U id)
{
	setfillstyle(WIDE_DOT_FILL,WHITE);
	floodfill(philosx[id],philosy[id],WHITE);
}
//***************************Eating()********************************************
void Eating(INT8U id)
{
	setfillstyle(SOLID_FILL,WHITE);
	floodfill(philosx[id],philosy[id],WHITE);
}

//*****************************Quitkey()********************************************
void Quitkey(void)
{
	if(PC_GetKey(&key)==TRUE)
	{
		if(key==0x1B)
			{restorecrtmode();PC_DOSReturn();}
	}
}

⌨️ 快捷键说明

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