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

优先级反转实验,使用信号量实现【RT-Thread学习笔记 5】的更多相关文章

  1. Boost Thread学习笔记三

    下面先对condition_impl进行简要分析.condition_impl在其构造函数中会创建两个Semaphore(信号量):m_gate.m_queue,及一个Mutex(互斥体,跟boost ...

  2. Boost Thread学习笔记五

    多线程编程中还有一个重要的概念:Thread Local Store(TLS,线程局部存储),在boost中,TLS也被称作TSS,Thread Specific Storage.boost::thr ...

  3. Boost Thread学习笔记四

    barrierbarrier类的接口定义如下:  1 class barrier : private boost::noncopyable   // Exposition only 2 { 3 pub ...

  4. Boost Thread学习笔记二

    除了thread,boost种:boost::mutexboost::try_mutexboost::timed_mutexboost::recursive_mutexboost::recursive ...

  5. Boost Thread学习笔记

    thread自然是boost::thread库的主 角,但thread类的实现总体上是比较简单的,前面已经说过,thread只是一个跨平台的线程封装库,其中按照所使用的编译选项的不同,分别决定使用 W ...

  6. thread学习笔记--BackgroundWorker 类

    背景: 在 WinForms 中,有时要执行耗时的操作,比如统计某个磁盘分区的文件夹或者文件数目,如果分区很大或者文件过多的话,处理不好就会造成“假死”的情况,或者报“线程间操作无效”的异常,或者在该 ...

  7. RabbitMQ学习笔记五:RabbitMQ之优先级消息队列

    RabbitMQ优先级队列注意点: 1.只有当消费者不足,不能及时进行消费的情况下,优先级队列才会生效 2.RabbitMQ3.5以后才支持优先级队列 代码在博客:RabbitMQ学习笔记三:Java ...

  8. ucos互斥信号量解决优先级反转问题

    在可剥夺性的内核中,当任务以独占方式使用共享资源的时候,会出现低优先级任务高于高优先级任务运行的情况,这种情况叫做优先级反转,对于实时操作系统而言,这是一场灾难,下面我们来说说优先级反转的典型环境. ...

  9. ucos之互斥信号量及优先级反转

    在ucos常使用共享资源来作为任务之间的通信方式,其中有:消息队列,信号量,邮箱,事件.信号量中又分二值信号,多值信号,互斥信号.这次主要讲二值信号与互斥信号之间区别和使用. 首先了解一下ucos的任 ...

随机推荐

  1. MySQL的左连接、右连接和全连接的实现

    表student:+----+-----------+------+| id | name | age |+----+-----------+------+| 1 | Jim | 18 || 2 | ...

  2. Maven学习笔记(1)之安装Maven

    此笔记是学习Maven时自己摸索+各种百度而来,并非全部原创,望与各位一同学习,勿拍~勿拍~ 安装步骤 1.下载Maven的最新版本,地址:http://maven.apache.org/downlo ...

  3. HBASE学习笔记-初步印象

    HBASE概念: HBASE是一个分布式架构的数据库,通过对数据进行多层的分块打散储存.从而改写传统数据库的储存能力和读取速度. HBASE的集群服务器: HBASE的集群主要分为Zookeeper集 ...

  4. C#拼接SQL语句,SQL Server 2005+,多行多列大数据量情况下,使用ROW_NUMBER实现的高效分页排序

    /// <summary>/// 单表(视图)获取分页SQL语句/// </summary>/// <param name="tableName"&g ...

  5. Android 学习第17课,使用文件的数据存储(4种存储模式)

    Context.MODE_PRIVATE:为默认操作模式,代表该文件是私有数据,只能被应用本身访问,在该模式下,写入的内容会覆盖原文件的内容,如果想把新写入的内容追加到原文件中.可以使用Context ...

  6. c51

    ORG 0000HMOV R7,#08HMOV 83H,#01HMOV R4,#00HAA1:CLR P3.6 CLR P3.4 SETB P3.6 DJNZ R7,AA1AA2:JB P3.0,AA ...

  7. BeanUtils.copyProperties和PropertyUtils.copyProperties的使用区别

    http://caoyaojun1988-163-com.iteye.com/blog/1871316

  8. SolidWorks的简单介绍及基本用法

    写这博客的动机来源于构建之法微信群里面的的一位老师.sw是一个强大的机械设计制图软件,我记得大一的时候学制图学的3d软件是inventor,而后发现sw用起来更方便更高效,于是就自学了sw,由于是自学 ...

  9. 信号量 semaphore 和 @synchronized 的运用

    1. //创建全局队列 dispatch_queue_t queue = dispatch_get_global_queue(0, 0); //创建信号量 dispatch_semaphore_t s ...

  10. C#的数组

    一维数组: 定义数组 int[] 变量名=new int [n]; 例一:输入班级人数,再输入每个人的姓名. 例二:输入班级人数,输入每个人的分数,求平均分 冒泡排序: 二维数组: 定义二维数组 in ...