μC/OS-II实验:实验三 信号量: 哲学家就餐问题

实验描述:
五个哲学家任务(ph1、ph2、ph3、ph4、ph5)主要有两种过程:思考(即睡眠一段时间)和就餐。每个哲学家任务在就餐前必须申请并获得一左一右两支筷子,就餐完毕后释放这两支筷子。五个哲学家围成一圈,每两人之间有一支筷子。一共有五支筷子,在该实验中用了五个互斥信号量来代表。如下图所示:
μC/OS-II实验:实验三 信号量: 哲学家就餐问题_第1张图片
实验手册的代码是错误的,看结果就晓得了,相邻的哲学家不可能一块吃饭。

涉及的μC/OS-II系统函数:
。。。

实验代码:
 app.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
void TaskPhiRepast( void* pdata)
{
    INT8U err;
    INT8U i,j;
     /* 第i个哲学家需要第i和j把筷子 */
    i = *( int*)pdata;
    j = (i+ 1) % N_TASKS;
    
     while( 1)
    {
        printf( "Philosopher %d is hungry... \r\n",i+ 1);
        OSTimeDly( 500);
        
        OSSemPend(ChopStick[i], 0,&err);
        OSSemPend(ChopStick[j], 0,&err);
        
        printf( "Philosopher %d is eating... \r\n",i+ 1);
        OSTimeDly( 500);
        
        printf( "Philosopher %d is thinking... \r\n",i+ 1);
        OSSemPost(ChopStick[i]);
        OSSemPost(ChopStick[j]);
    }
}

 app.h
1
2
GLOBAL OS_EVENT*    ChopStick[N_TASKS];
GLOBAL INT8U        TaskData[N_TASKS];


 app_cfg.h
1
2
3
4
5
#define PHI_REPAST_STK_SIZE  64
#define PHI_REPAST_TASK_Prio  3
#define     N_TASKS          5
GLOBAL OS_STK   TASK_PHI_REPAST[N_TASKS][PHI_REPAST_STK_SIZE];
void TaskPhiRepast( void* pdata);

 main.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
  int main( void)
 {
    INT8U i;
     
    BSP_Init();
    
    OSInit();
     for(i =  0;i < N_TASKS;i++)
    {
        TaskData[i] = i;
        ChopStick[i] = OSSemCreate( 1);
         if(ChopStick[i] != (OS_EVENT*) 0)
            printf( "ChopStick %d is created no error \r\n",i);
    }
    OSTaskCreate( TaskStart,
                    ( void *) 0,   //parameter
                    (OS_STK *)&TASK_START_STK[START_STK_SIZE- 1],
                    START_TASK_Prio );
    OSStart();
     
     return  0;    
 }

 main.c:TaskStart
1
2
3
4
5
6
7
8
9
10
11

/* 实验三  信号量:哲学家就餐问题的实现 */
for(i =  0; i < N_TASKS; i++)
{
    err = OSTaskCreate(TaskPhiRepast, ( void *)&TaskData[i], (OS_STK *)&TASK_PHI_REPAST[i][PHI_REPAST_STK_SIZE -  1], PHI_REPAST_TASK_Prio + i);
     if(err == OS_NO_ERR)
    {
        printf( "Philosophor %d is created no error \r\n", i);
    }
}

实验结果:
μC/OS-II实验:实验三 信号量: 哲学家就餐问题_第2张图片
注意:如果将信号量的建立放在TaskStart中,则结果出错,出现以下情况,原因未知。
μC/OS-II实验:实验三 信号量: 哲学家就餐问题_第3张图片
教训:最好将“事件”的建立放在“任务”的建立之前。
感受:多任务系统的调试真心难啊,到处乱跳,而且JLink对硬断点的设置个数有限制(貌似只有6个),一旦设置多了,MDK自动崩溃。(用仿真环境调试,其断点个数貌似没有限制,想设置多少设置多少,但是它不会触发中断和异常。)

你可能感兴趣的:(操作系统篇:μC/OS-II,uCOS-II,哲学家就餐问题)