五个哲学家任务(ph1、ph2、ph3、ph4、ph5)主要有两种过程:思考(即睡眠一段时间)和就餐。每个哲学家任务在就餐前必须申请并获得一左一右两支筷子,就餐完毕后释放这两支筷子。五个哲学家围成一圈,每两人之间有一支筷子。一共有五支筷子,在该实验中用了五个互斥信号量来代表。
程序:
#include "includes.h"
#define TASK_STK_SIZE 512
void StartTask(void *pdata);
void TASK(void *pdata);
void Task(void *pdata);
OS_STK StartTaskStk[TASK_STK_SIZE];
OS_STK Task1Stk[TASK_STK_SIZE];
OS_STK Task2Stk[TASK_STK_SIZE];
OS_STK Task3Stk[TASK_STK_SIZE];
OS_STK Task4Stk[TASK_STK_SIZE];
OS_STK Task5Stk[TASK_STK_SIZE];
INT16S key;
INT8U err;
INT8U y=0;
int sit[5]={0,1,2,3,4};
OS_EVENT*Semp[5];
char*sr[5];
char*st[5];
void main (void)
{
int i;
OSInit();
PC_DOSSaveReturn();
PC_VectSet(uCOS, OSCtxSw);
sr[0]="Task1 is running";
sr[1]="Task2 is running";
sr[2]="Task3 is running";
sr[3]="Task4 is running";
sr[4]="Task5 is running";
st[0]="Task1 is thinking";
st[1]="Task2 is thinking";
st[2]="Task3 is thinking";
st[3]="Task4 is thinking";
st[4]="Task5 is thinking";
for(i=0;i<5;i++) Semp[i]=OSSemCreate(1);
OSTaskCreate(StartTask,(void*)0,&StartTaskStk[TASK_STK_SIZE - 1],0);
OSStart();
}
void StartTask (void *pdata)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr;
#endif
pdata = pdata;
OS_ENTER_CRITICAL();
PC_VectSet(0x08, OSTickISR);
PC_SetTickRate(OS_TICKS_PER_SEC);
OS_EXIT_CRITICAL();
OSStatInit();
OSTaskCreate(Task,(int*)&sit[0],&Task1Stk[TASK_STK_SIZE-1],1);
OSTaskCreate(Task,(int*)&sit[1],&Task2Stk[TASK_STK_SIZE-1],2);
OSTaskCreate(Task,(int*)&sit[2],&Task3Stk[TASK_STK_SIZE-1],3);
OSTaskCreate(Task,(int*)&sit[3],&Task4Stk[TASK_STK_SIZE-1],4);
OSTaskCreate(TASK,(int*)&sit[4],&Task5Stk[TASK_STK_SIZE-1],5);
for (;;)
{
if(PC_GetKey(&key)==TRUE)
{
if(key==0x1B)
{
PC_DOSReturn();
}
}
OSTimeDlyHMSM(0,0,3,0);
}
}
void TASK(void *pdata)
{
#if OS_CRITICAL_METHOD==3
OS_CPU_SR cpu_sr;
#endif
pdata=pdata;
for(;;)
{
OSSemPend(Semp[0],0,&err);
OSSemPend(Semp[4],0,&err);
PC_DispStr(10,++y,sr[(*(int*)pdata)],DISP_BGND_BLACK+DISP_FGND_WHITE);
OSTimeDly(300);
PC_DispStr(30,++y,st[(*(int*)pdata)],DISP_BGND_BLACK+DISP_FGND_WHITE);
OSSemPost(Semp[0]);
OSSemPost(Semp[4]);
OSTimeDlyHMSM(0,0,(*(int*)pdata)+1,0);
}
}
void Task(void *pdata)
{
#if OS_CRITICAL_METHOD==3
OS_CPU_SR cpu_sr;
#endif
pdata=pdata;
for(;;)
{
OSSemPend(Semp[(*(int*)pdata)],0,&err);
OSSemPend(Semp[(*(int*)pdata)+1],0,&err);
PC_DispStr(10,++y,sr[(*(int*)pdata)],DISP_BGND_BLACK+DISP_FGND_WHITE);
OSTimeDly(300);
PC_DispStr(30,++y,st[(*(int*)pdata)],DISP_BGND_BLACK+DISP_FGND_WHITE);
OSSemPost(Semp[(*(int*)pdata)]);
OSSemPost(Semp[(*(int*)pdata)+1]);
OSTimeDlyHMSM(0,0,(*(int*)pdata)+1,0);
}
}
结果:
程序设置5个信号量,表示5支筷子。
前四个人拿筷子的顺序相同,采用同一个程序任务。
最后一个人拿筷子顺序相反,调用不同的程序,依此来避免死锁问题。