优先级反转实验,使用信号量实现【RT-Thread学习笔记 5】
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】的更多相关文章
- Boost Thread学习笔记三
下面先对condition_impl进行简要分析.condition_impl在其构造函数中会创建两个Semaphore(信号量):m_gate.m_queue,及一个Mutex(互斥体,跟boost ...
- Boost Thread学习笔记五
多线程编程中还有一个重要的概念:Thread Local Store(TLS,线程局部存储),在boost中,TLS也被称作TSS,Thread Specific Storage.boost::thr ...
- Boost Thread学习笔记四
barrierbarrier类的接口定义如下: 1 class barrier : private boost::noncopyable // Exposition only 2 { 3 pub ...
- Boost Thread学习笔记二
除了thread,boost种:boost::mutexboost::try_mutexboost::timed_mutexboost::recursive_mutexboost::recursive ...
- Boost Thread学习笔记
thread自然是boost::thread库的主 角,但thread类的实现总体上是比较简单的,前面已经说过,thread只是一个跨平台的线程封装库,其中按照所使用的编译选项的不同,分别决定使用 W ...
- thread学习笔记--BackgroundWorker 类
背景: 在 WinForms 中,有时要执行耗时的操作,比如统计某个磁盘分区的文件夹或者文件数目,如果分区很大或者文件过多的话,处理不好就会造成“假死”的情况,或者报“线程间操作无效”的异常,或者在该 ...
- RabbitMQ学习笔记五:RabbitMQ之优先级消息队列
RabbitMQ优先级队列注意点: 1.只有当消费者不足,不能及时进行消费的情况下,优先级队列才会生效 2.RabbitMQ3.5以后才支持优先级队列 代码在博客:RabbitMQ学习笔记三:Java ...
- ucos互斥信号量解决优先级反转问题
在可剥夺性的内核中,当任务以独占方式使用共享资源的时候,会出现低优先级任务高于高优先级任务运行的情况,这种情况叫做优先级反转,对于实时操作系统而言,这是一场灾难,下面我们来说说优先级反转的典型环境. ...
- ucos之互斥信号量及优先级反转
在ucos常使用共享资源来作为任务之间的通信方式,其中有:消息队列,信号量,邮箱,事件.信号量中又分二值信号,多值信号,互斥信号.这次主要讲二值信号与互斥信号之间区别和使用. 首先了解一下ucos的任 ...
随机推荐
- 如何将C#类库做成COM
在类库项目的属性中, 选择生成, 最下方的"为COM的互操作注册"进行勾选, 并且将项目的Properties中, AssemblyInfo.cs中的[assembly: ComV ...
- vue学习笔记
来公司以后就一直在用vue框架,不管是业务代码,还是做vue组件.关于vue有一些点是文档中没有提及的,记录一下以便以后查询- 一.Vue的特点 新一代 Vue.js 框架非常关注如何用极少的外部特性 ...
- 缺少动态连接库.so--cannot open shared object file: No such file or directory
总结下来主要有3种方法:1. 用ln将需要的so文件链接到/usr/lib或者/lib这两个默认的目录下边 ln -s /where/you/install/lib/*.so /usr/lib sud ...
- WIN32服务程序(一):创建服务
MSDN中有安装服务的例子Installing a Service(可点击进入),我们这里的创建服务,和MSDN里的例子基本上是一样的.这里做一些简单的说明: 打开控制面板,管理工具,服务.我们看到的 ...
- (进阶篇)PHP实现用户注册后邮箱验证,激活帐号
我们在很多网站注册会员时,注册完成后,系统会自动向用户的邮箱发送一封邮件,这封邮件的内容就是一个URL链接,用户需要点击打开这个链接才能激活之前在该网站注册的帐号.激活成功后才能正常使用会员功能. 本 ...
- VIM-Sed常用的一些记录。。。逐渐学习。。
:[range]co[py] {address} :t :[range]m[ove] {address] 例如 :1,3t10 1-3行复制到10行后.用m就是移动了. :sort / / // ...
- [翻译] LTE/LTE-Advanced for Mobile Broadband-10.4
10.4 下行L1/L2控制信令 上下行信道的数据传输,需要特定的“下行控制信令”提供支持.下行控制信令通常被称为“下行L1/L2控制信令”,这表示该控制信令部分来自物理层(L1),部分来自MAC层( ...
- UML(一) 类图及类间关系
原创文章,同步发自作者个人博客,http://www.jasongj.com/uml/class_diagram/ UML类图 UML类图介绍 在UML 2.*的13种图形中,类图是使用频率最高的UM ...
- JavaScript模块化编程
为什么模块化很重要?因为有了模块,我们就可以更方便的使用别人的代码,想要什么功能,就加载什么模块. 万事都有规矩,就是规范化! 目前,通行的Javascript模块规范有两种: CommonJS和AM ...
- 设置jdk的编码
在环境变量中: AVA_TOOL_OPTIONS-Dfile.encoding=utf-8 -Duser.language=en -Duser.country=US