优先级反转实验,使用信号量实现【RT-Thread学习笔记 5】

时间:2023-01-14 16:41:03

RTOS中很经典的问题。就是在使用共享资源的时候,优先级低的进程在优先级高的进程之前执行的问题。这里模拟这种情况。

下面的实验模拟了优先级反转的情况:

先定义三个线程:

//优先级反转实验
rt_sem_t sem;
rt_uint32_t t1_count = ,t2_count = ,worker_count = ;
rt_thread_t t1,t2,worker ;

void pri1_entry(void *parameter)
{
    rt_err_t result;
    )
    {
        result = rt_sem_take(sem,RT_WAITING_FOREVER);
        ;t1_count<;t1_count++)
        {
            rt_kprintf("pri1 take semphone\r\n");
            rt_thread_delay(RT_TICK_PER_SECOND);
        }
        rt_kprintf("pri1 release semphone\r\n");
        rt_sem_release(sem);
    }
}

void pri2_entry(void *parameter)
{
    //rt_uint32_t t2_count = 0;
    rt_err_t result;
    )
    {
        result = rt_sem_take(sem,RT_WAITING_FOREVER);
        rt_kprintf("pri2 take semphone\r\n");
        if(result != RT_EOK)
        {
            return;
        }
        rt_kprintf("pri2 release semphone\r\n");
        rt_sem_release(sem);

        rt_thread_delay();
        result = rt_sem_take(sem,RT_WAITING_FOREVER);
        t2_count ++;
        rt_kprintf("pri2 :got semphone,count:%d\r\n",t2_count);
        result = rt_sem_release(sem);
    }

}

void worker_entry(void *parameter)
{
    rt_thread_delay();
    ;worker_count<;worker_count++)
    {
        rt_kprintf("worker:  count: %d\n", worker_count);
    }
    rt_thread_delay(RT_TICK_PER_SECOND);

}

启动三个线程:

//信号量/优先级反转实验

    t1 = rt_thread_create("pri1",
        pri1_entry, RT_NULL,
        , , );
    if (t1 != RT_NULL)
        rt_thread_startup(t1);

    t2 = rt_thread_create("pri2",
            pri2_entry, RT_NULL,
            , , );
        if (t2 != RT_NULL)
            rt_thread_startup(t2);

    worker = rt_thread_create("worker",
            worker_entry, RT_NULL,
            , , );
    if (worker != RT_NULL)
        rt_thread_startup(worker);
sem = rt_sem_create(,RT_IPC_FLAG_PRIO);

三个线程的优先级分别是:pri1:8 pri2:6 worker:7

程序开始运行时,上进程均处于就绪状态。此时pri2进程优先级最高开始执行,它先申请信号量之后释放。此时进程pri1和worker都处于就绪状态,worker进程进入后先休眠。进程pri1开始执行。

进程pri1申请信号量,开始输出。此后,进程pri2就绪但它申请信号量的时候发现信号量被使用了,于是就开始等待信号量。进程worker就绪后,抢占pri1的开始执行。

于是就出现了高优先级进程pri2处于等待状态,而低优先级进程worker处于执行状态这种情况。

Pr1占用sem时候,pri2处于等待sem状态,worker就绪了,worker抢占pri1的CPU执行。造成了worker的优先级没有pri2高,却在pri2之前执行。

通过串口输出的结果可以看得更清楚些:


\ | /
- RT -     Thread Operating System
/ | \     2.0.0 build Aug 29 2014
2006 - 2013 Copyright by rt-thread team
pri2 take semphone
pri2 release semphone
pri1 take semphone
finsh>>worker:  count: 0
worker:  count: 1
worker:  count: 2
worker:  count: 3
worker:  count: 4
worker:  count: 5
worker:  count: 6
worker:  count: 7
worker:  count: 8
worker:  count: 9
pri1 take semphone
pri1 take semphone
pri1 take semphone
pri1 take semphone
pri1 take semphone
pri1 take semphone
pri1 take semphone
pri1 take semphone
pri1 take semphone
pri1 release semphone
pri2 :got semphone,count:1
pri2 take semphone