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. 【LeetCode】Roman to Integer & Integer to Roman

    Roman to Integer Given a roman numeral, convert it to an integer. Input is guaranteed to be within t ...

  2. 我们正在等待一次技术革命的到来; We are waiting for the arrival of a technological revolution

    In the future, there must be a significant technological revolution just like Industrial Revolution. ...

  3. Android自定义权限和使用权限

    本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处! 自定义权限,主要用于保护被赋予权限的组件.如无权限与有权限,正如public与private的对类保 ...

  4. C#通过WatiN操作页面中内嵌的Iframe

    通过WatiN.Core.Broswer.Frame()方法来获取iframe对象,之后的容器就是frame,然后进行操作. 下面的例子是登录QQ空间的: Frame frame = browser. ...

  5. java mail使用qq邮箱发邮件的配置方法

    最近自己折腾了下Java中利用mai发送QQ邮件 1.QQ邮箱设置 1.1 进去QQ邮箱-->设置-->账号-->进行设置如下图 2.foxmail设置(由于我要利用它收邮件) 2. ...

  6. iOS Block循环引用

    在介绍block循环引用前我们先了解一下typeof. typeof是什么??? typeof 是一个一元运算,放在一个运算数之前,运算数可以是任意类型. 它返回值是一个字符串,该字符串说明运算数的类 ...

  7. discuz不能发表投票、附件上传等

    如何开启和发表投票主题 本教程主要讲述如何开启和发表投票的帖子.具体的操作如下: 1.论坛后台 => 用户 => 用户组 => 详情 => 特殊主题 => 允许发起投票设 ...

  8. 利用 ipset 封禁大量 IP

    使用 iptables 封 IP,是一种比较简单的应对网络攻击的方式,也算是比较常见.有时候可能会封禁成千上万个 IP,如果添加成千上万条规则,在一台注重性能的服务器或者本身性能就很差的设备上,这就是 ...

  9. XAMPP 的安装配置(Linux 版)

    --姜庭华  msn: jaimejth@live.cn --博客:http://blog.csdn.net/jaimejth 软件下载在以下网站 http://www.apachefriends.o ...

  10. 关于django xadmin的学习改造(菜单名称,更改默认前缀数据库)

    路径xadmin-master\demo_app\app\models.py class c(models.Model): ip_address = models.CharField(max_leng ...