📄 test.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 + -