Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
DIY综合交流区
[RealTouch例程]线程优先级反转原理
发布于 2012-09-01 15:07:19 浏览:5328
订阅该版
实验目的 ? 介绍实时操作系统中的经典问题,优先级反转 硬件说明 本实验使用RT-Thread官方的Realtouch开发板作为实验平台。涉及到的硬件主要为 ? 串口3,作为rt_kprintf输出,需要连接JTAG扩展板 具体请参见《Realtouch开发板使用手册》 实验原理及程序结构 优先级反转是实时操作系统中的经典问题之一,由于多线程共享资源,具有最高优先级的线程被低优先级线程阻塞,反而使中优先级线程先于高优先级线程执行,导致系统故障。 优先级反转的一个典型场景为:系统中存在优先级为A、B和C的三个线程,优先级A > B > C,线程A,B处于挂起状态,等待某一事件的发生,线程C正在运行,此时线程C开始使用某一共享资源S。在使用过程中,线程A等待的事件到来,线程A转为就绪态,因为它比线程C优先级高,所以立即执行。但是当线程A要使用共享资源S时,由于其正在被线程C使用,因此线程A被挂起切换到线程C运行。如果此时线程B等待的事件到来,则线程B转为就绪态。由于线程B的优先级比线程C高,因此线程B开始运行,直到其运行完毕,线程C才开始运行。只有当线程C释放共享资源S后,线程A才得以执行。在这种情况下,优先级发生了反转,线程B先于线程A运行。这样便不能保证高优先级线程的响应时间。可见图1-1 ![priority.png](/uploads/88_b40bdca7aaf248657b9fcda5e2c86c0f.png) 图1-1 实验设计 本实验的主要设计目的是帮助读者进一步了解优先级反转的实际运行情况,有助于了解优先级反转的原理。 源程序说明 本实验对应1_kernel_prioinvert 系统依赖 在rtconfig.h中需要开启 ``` #define RT_USING_HEAP``` 此项可选,开启此项可以创建动态线程和动态信号量,如果使用静态线程和静态信号量,则此项不是必要的 ``` #define RT_USING_CONSOLE``` 此项必须,本实验使用rt_kpriintf向串口打印按键信息,因此需要开启此项 主程序说明 在applications/application.c中定义了三个线程,分别是t1, t2, worker,以及一个动态信号量sem ```t1 = rt_thread_create("t1", thread1_entry, RT_NULL, 512, 8, 10); if (t1 != RT_NULL) rt_thread_startup(t1); t2 = rt_thread_create("t2", thread2_entry, RT_NULL, 512, 6, 10); if (t2 != RT_NULL) rt_thread_startup(t2); worker = rt_thread_create("worker", worker_thread_entry, RT_NULL, 512, 7, 10); if (worker != RT_NULL) rt_thread_startup(worker); sem = rt_sem_create("sem", 1, RT_IPC_FLAG_PRIO); if (sem == RT_NULL) { return 0; } ``` 下面的代码是三个线程的入口程序, ```static void thread1_entry(void* parameter) { rt_err_t result; result = rt_sem_take(sem, RT_WAITING_FOREVER); for(t1_count = 0; t1_count < 10; t1_count ++) { rt_kprintf("thread1: got semaphore, count: %d ", t1_count); rt_thread_delay(RT_TICK_PER_SECOND); } rt_kprintf("thread1: release semaphore "); rt_sem_release(sem); } static void thread2_entry(void* parameter) { rt_err_t result; while (1) { result = rt_sem_take(sem, RT_WAITING_FOREVER); rt_kprintf("thread2: got semaphore "); if (result != RT_EOK) { return; } rt_kprintf("thread2: release semaphore "); rt_sem_release(sem); rt_thread_delay(5); result = rt_sem_take(sem, RT_WAITING_FOREVER); t2_count ++; rt_kprintf("thread2: got semaphore, count: %d ", t2_count); } } static void worker_thread_entry(void* parameter) { rt_thread_delay(5); for(worker_count = 0; worker_count < 10; worker_count++) { rt_kprintf("worker: count: %d ", worker_count); } rt_thread_delay(RT_TICK_PER_SECOND); } ```编译调试及观察输出信息 编译请参见《RT-Thread配置开发环境指南》完成编译烧录,参考《Realtouch开发板使用手册》完成硬件连接,连接扩展板上的串口和jlink,运行后可以看到如下信息: | / - RT - Thread Operating System / | 1.1.0 build Aug 10 2012 2006 - 2012 Copyright by rt-thread team thread2: got semaphore thread2: release semaphore thread1: got semaphore, count: 0 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 thread1: got semaphore, count: 1 thread1: got semaphore, count: 2 thread1: got semaphore, count: 3 thread1: got semaphore, count: 4 thread1: got semaphore, count: 5 thread1: got semaphore, count: 6 thread1: got semaphore, count: 7 thread1: got semaphore, count: 8 thread1: got semaphore, count: 9 thread1: release semaphore thread2: got semaphore, count: 1 …. 结果分析 三个线程的优先级顺序是 thread2 > worker > thread1,首先thread2得到执行,它得到信号量,并且释放,然后延时等待,然后worker线程得到处理器控制权开始运行,它也进行了延时操作,然后,thread1拿到了控制权,并且它申请得到了信号量,接着进行了打印操作,在它打印结束进行延时操作时,由于worker的优先级高于thread1,worker重新获得了控制,由于它并不需要信号量来完成下面的操作,于是很顺利的它把自己的一大串打印任务都执行完成了,纵然thread2的优先级要高于它,但是奈何获取不到信号量,什么也干不了,只能被阻塞而干等,于是实验原理中提到的那一幕便发生了。worker执行结束后,执行权回到了握有信号量的thread1手中,当它完成自己的操作,并且释放信号量后,优先级最高的thread2才能继续执行。 这其中所发生的就是优先级反转,低优先级的任务反而抢占了高优先级的任务,这种情况在实时系统中是不允许发生的,下一章会介绍如何解决这类问题; ![实验1_6线程优先级反转原理.pdf](/uploads/88_8029e4b412aee4db6f2e91f00c233512.pdf) ![1_kernel_thread_priority_inversion.zip](/uploads/88_596f84ee8b949e91f12df2b438232702.zip)
查看更多
3
个回答
默认排序
按发布时间排序
celticzy
2012-12-23
这家伙很懒,什么也没写!
优先级顺序"thread2 > thread1 > worker" 这句打错了
wangway
2013-01-01
这家伙很懒,什么也没写!
>优先级顺序"thread2 > thread1 > worker" >这句打错了 --- 应是:"thread2 > worker > thread1"
撰写答案
登录
注册新账号
关注者
0
被浏览
5.3k
关于作者
shaolin
这家伙很懒,什么也没写!
提问
115
回答
444
被采纳
0
关注TA
发私信
相关问题
1
[项目]搞个开源的硬件项目
2
硬件计划贴,及时更新,欢迎提意见
3
软件计划贴,及时更新,欢迎提意见::WMA,MOUNT,LWIP等问题急需解决.
4
MMS协议
5
定点的wma解压库-libwma
6
QQ群记录 [20090821]
7
STM32网络收音机PCB报名征集
8
第一版调试记录
9
第二版硬件讨论
10
RADIO项目相关模块规格--欢迎大家自己做板时规格与此兼容,减少重复劳动
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
最新文章
1
使用百度AI助手辅助编写一个rt-thread下的ONVIF设备发现功能的功能代码
2
RT-Thread 发布 EtherKit开源以太网硬件!
3
rt-thread使用cherryusb实现虚拟串口
4
《C++20 图形界面程序:速度与渲染效率的双重优化秘籍》
5
《原子操作:程序世界里的“最小魔法单位”解析》
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
WIZnet_W5500
UART
ota在线升级
PWM
cubemx
freemodbus
flash
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
Debug
编译报错
msh
SFUD
keil_MDK
rt_mq_消息队列_msg_queue
ulog
C++_cpp
at_device
本月问答贡献
踩姑娘的小蘑菇
7
个答案
3
次被采纳
a1012112796
13
个答案
2
次被采纳
张世争
9
个答案
2
次被采纳
rv666
5
个答案
2
次被采纳
用户名由3_15位
11
个答案
1
次被采纳
本月文章贡献
程序员阿伟
8
篇文章
2
次点赞
hhart
3
篇文章
4
次点赞
大龄码农
1
篇文章
3
次点赞
ThinkCode
1
篇文章
1
次点赞
Betrayer
1
篇文章
1
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部