㈠ 如何防止优先级反转及其继承 - 如何为远程医疗设备选择合适的实时操作系统
防止优先级反转 操作系统中最令人头疼的错误是优先级反转。它是指低优先级任务阻止高优先级任务完成运行的状态。例如,在报警控制、数据记录仪和数据聚合器共享资源的病人监控系统里,优先级高的任务(报警控制器)必须等待优先级低的任务(数据记录器)结束才能继续运行。第三项任务(数据聚合器)的优先级比报警控制器的低,但比数据记录器的高。数据聚合器会抢占数据记录器的优先级,进而抢占报警控制器的优先级,这就无法满足实时提交的要求。 优先级继承 优先级继承是指将被阻止的高优先级任务的优先级分配给阻止任务的低优先级线程,直至完成被阻止的任务,以此防止优先级反转。例如,数据记录器可继承报警控制器的优先级,这样它就不会被数据聚合器抢占。当任务结束后,它会恢复最初的优先级,报警控制器会解除阻止并继续运行。
图4 优先级继承防止优先级反转 确保可用性 对许多系统来说,资源的可用性至关重要。假如某一子系统出现CPU周期匮乏,会导致十分严重的后果。例如,如果心脏监护仪的连接中断可能导致中心监护系统误认为出现报警情况并派出急救人员,或当病人真出现危急状况时,系统却无法发出报警信息。 根据以往经验,解决这一问题的途径是更新硬件或重新设计软件。虽然将新设计的软件发送到联网的医疗设备上是一个可行方案,但这不仅使成本高昂,而且还可能导致该设备已有的产品认证失效。 分区分区技术通过执行CPU预算并防止进程独占CPU周期,使资源匮乏的问题迎刃而解。可选择两种类型的分区:固定式和自适应式。 采用固定分区,系统设计人员为每个任务指定分配的CPU时间。分区内的任务消耗的CPU时间都不能超过分区时已分配的时间比例,以便于其他分区内的进程保持随时可用,进而保证所有关键进程随时可用。 遗憾的是,采用固定分区时,即使分配到其他地方的周期未被使用,另一个分区内的进程也无法使用,因为它不能使用超出其所在分区预先分配的CPU周期,固定分区虽然能防止系统出现资源匮乏,但它却浪费了CPU周期,而且削弱了系统应对高峰需求的能力。 与固定分区类似,自适应分区也能防止资源匮乏。然而,自适应分区采用一种动态调度算法将一个分区内闲置的CPU周期重新分配到另一个需要更多处理时间的分区内。当多个分区内的进程争夺CPU周期时,自适应分区会执行资源分配。这样,设计人员就能充分依赖系统资源保证,不必再为固定分区造成的处理能力降低而寻找良策了。 监视、停止或重启进程 防止整个系统的进程发生连锁故障和自我修复功能对可信赖的操作系统至关重要。需确保系统可用性的设备可采用面向硬件的高可用性解决方案和软件监视程序。 监视程序监视系统并进行多级恢复或按要求平稳关机。根据执行方式的不同,当出现故障时它应:先终止然后重启出现故障的进程而无需重启系统,或者,终止故障进程和相关进程,初始化硬件使其进入“安全”状态,然后以协调方式重启终止的进程,或者,如故障比较严重或危及安全,能以受控方式关机或使整个系统复位,并向系统操作员发出报警。 在所有情况下,监视程序都必须能自我监控并灵活响应内部故障。如果监视程序意外停止,它必须通过一个镜像进程复制本身的状态。 最后,软件监视程序能监视传统硬件监视程序看不到的系统事件。例如,硬件监视程序能确保驱动程序为硬件服务,但却很难检测到其他程序是否正与该驱动程序正确通话。软件监视程序能弥补这一不足,它会在驱动程序本身出现问题前采取行动。 结论 发达国家的人口老龄化趋势和健康预算紧缩都促使医疗服务方式由常规医院模式向远程医疗和家庭自助模式转变。这些变化和最新技术推动远程医疗设备的市场不断扩大,其发展速度之快在十年前是难以想象的。 设备制造商通过认真分析所选操作系统的性能特征,从而降低成本并提升其产品顺利通过行业认证而在市场上大获成功的机会。
㈡ 优先级反转有什么危害
简答:
优先级反转的危害:
由于优先级反转,造成任务调度时,时间的不确定性。
时间不确定,破坏了实时系统的实时性
严重时可能导致系统崩溃
由于本身基于优先级设计的任务,每个优先级不同的任务,往往对应着实际的现实中的执行的任务
其优先级反转,导致低优先级比高优先级先执行了
直接就导致任务错乱,逻辑错乱了
程序也就异常了?(待确定此部分的理解是否有误)
详解:
【整理】什么是优先级反转+有何危害+如何避免和解决
(此处无法贴地址,请自行google搜标题即可找到)
㈢ 优先级的优先级反转的发生的防止
ucos中可以利用互斥型信号量解决上述问题。互斥型信号量创建函数申请一个比使用某共享资源的所有进程中比最高优先级更高的优先级作为预留。当某个进程调用pend函数申请使用该共享资源,同时该资源已经被占用时,pend函数会判断是否需要提升占用该资源进程的优先级,以使其尽快释放所占用的资源,从而防止优先级反转的发生 。
㈣ 请教下面的数据结构程序
1 读程序段,回答问题
int main(int argc,char *argv[])
{
int c=9,d=0;
c=c++%5;
d=c;
printf("d=%d\n",d);
return 0;
}
a) 写出程序输出
b) 在一个可移植的系统中这种表达式是否存在风险?why?
#include "stdio.h"
int a=0;
int b;
static char c;
int main(int argc,char *argv[])
{
char d=4;
static short e;
a++;
b=100;
c=(char)++a;
e=(++d)++;
printf("a=%d, b=%d, c=%d, d= %d, e=%d",a,b,c,d,e);
return 0;
}
a) 写出程序输出
b) 编译器如果安排各个变量(a,b,c,d)在内存中的布局(eg. stack,heap,data section,bss section),最好用图形方式描述。
2 中断是嵌入式系统中重要的组成部分,这导致了许多编译开发商提供一种扩展:让标准C支持中断,产生了一个新的关键字__interrupt。下面的代码就使用了__interrupt关键字去定义了一个中断服务子程序(ISR),请评论以下这段代码。
__interrupt double compute_area(double radius)
{
double area = PI * radius *radius;
printf("nArea = %f", area);
return area;
}
3 C/C++基础知识问题
a) 关键字volatile在编译时有什么含义?并给出三个不同使用场景的例子(可以伪代码或者文字描述)。
b) C语言中static关键字的具体作用有哪些 ?
c) 请问下面三种变量声明有何区别?请给出具体含义
int const *p;
int* const p;
int const* const p;
4 嵌入式系统相关问题
a) 对于整形变量A=0x12345678,请画出在little endian及big endian的方式下在内存中是如何存储的。
b) 在ARM系统中,函数调用的时候,参数是通过哪种方式传递的?
c) 中断(interrupt,如键盘中断)与异常(exception,如除零异常)有何区别?
5 设周期性任务P1,P2,P3的周期为T1,T2,T3分别为100,150,400;执行时间分别为20,40,100。请设计一种调度算法进行任务调度,满足任务执行周期及任务周期。
6 优先级反转问题在嵌入式系统中是一中严重的问题,必须给与足够重视。
a) 首先请解释优先级反转问题
b) 很多RTOS提供优先级继承策略(Priority inheritance)和优先级天花板策略(Priority ceilings)用来解决优先级反转问题,请讨论这两种策略。
参考答案:
1 5
存在风险,因为c=c++%5;这个表达式对c有两次修改,行为未定义,c的值不确定
int a=0; // data section
int b; // data section
static char c; // BSS
int main(int argc,char *argv[])
{
char d=4; // stack
static short e; // BSS
a++;
b=100;
c=(char)++a;
e=(++d)++;
printf("a=%d, b=%d, c=%d, d= %d, e=%d",a,b,c,d,e);
return 0;
}
a=2,b=100,c=2,d=6,e=5
2 a)ISR不能返回一个值;
b)ISR不能传递参数;
c)浮点一般都是不可重入的;
d)printf函数有重入和性能上的问题。
3 a) 用volatile关键字定义变量,相当于告诉编译器,这个变量的值会随时发生变化,每次使用时都需要去内存里
重新读取它的值,并不要随意针对它作优化。
建议使用volatile变量的场所:
(1) 并行设备的硬件寄存器
(2) 一个中断服务子程序中会访问到的非自动变量(全局变量)
(3) 多线程应用中被几个任务共享的变量
b) 在函数体,一个被声明为静态的变量在这一函数被调用过程中维持其值不变。
在模块内(但在函数体外),一个被声明为静态的变量可以被模块内所用函数访问,但不能被模块外其它函数
访问。它是一个本地的全局变量。
在模块内,一个被声明为静态的函数只可被这一模块内的其它函数调用。那就是,这个函数被限制在声明它的
模块的本地范围内使用。
static全局变量与普通的全局变量有什么区别:static全局变量只初使化一次,防止在其他文件单元中被引用;
static局部变量和普通局部变量有什么区别:static局部变量只被初始化一次,下一次依据上一次结果值;
static函数与普通函数有什么区别:static函数在内存中只有一份,普通函数在每个被调用中维持一份拷贝
c) 一个指向常整型数的指针
一个指向整型数的常指针
一个指向常整型数的常指针
4
a) 0x12345678
little endian big endian 刚好反过来
高地址--〉 0x12 低地址--〉 0x12
0x34 0x34
0x56 0x56
低地址--〉 0x78 高地址--〉 0x78
b)参数<=4时候,通过R0~R3传递,>4的通过压栈方式传递
c) 异常:在产生时必须考虑与处理器的时钟同步,实践上,异常也称为同步中断。在处理器执行到由于编程失误而导致的错误指令时,或者在执行期间出现特殊情况(如缺页),必须靠内核处理的时候,处理器就会产生一个异常。
所谓中断应该是指外部硬件产生的一个电信号,从cpu的中断引脚进入,打断cpu当前的运行;
所谓异常,是指软件运行中发生了一些必须作出处理的事件,cpu自动产生一个陷入来打断当前运行,转入异常处理流程。
异步与同步的区别`
5
6 高优先级任务需要等待低优先级任务释放资源,而低优先级任务又正在等待中等优先级任务的现象叫做优先级反转
优先级继承策略(Priority inheritance):继承现有被阻塞任务的最高优先级作为其优先级,任务退出临界区,恢
复初始优先级。
优先级天花板策略(Priority ceilings):控制访问临界资源的信号量的优先级天花板。
优先级继承策略对任务执行流程的影响相对教小,因为只有当高优先级任务申请已被低优先级任务占有的临界资源
这一事实发生时,才抬升低优先级任务的优先级
㈤ 在嵌入式实时操作中优先级反转,死锁会给系统带来什么后果
死锁
在多道程序系统中,多个进程序并发执行,共享系统资源,从而提高了资源利用率和系统吞吐量,但可能发生一种危险----死锁。所谓死锁,是指多个进程因竞争资源而形成的一种僵局,若无外力作用,这些进程都将永远不能再向前推进。
(1)产生死锁的原因和必要条件
A、产生死锁的原因
产生死涣的主要原因可归结为以下两点
(1)竞争资源
(2)进程推进顺序不当。
B、产生死锁的必要条件
(1)互斥条件
一个资源在一段时间内只能被一个进程所使用,具有排它性。
(2)请求和保持条件
一个进程在请求新资源而阻塞时,对已获得资源又保持不放。
(3)不剥夺条件
进程已获得的资源,在未使用完之前不能被剥夺,只能在使用完时由自己释放。
(4)环路等待条件
在发生死锁时,必然存在一个进程--------资源的环形链.即进程集合{P1,p2,....,Pn}中的P1正在等待P2占用的资源,P2正在等待P3占用的资源,....,Pn正在等待P1占用的资源.
只要同时具备上述4个必要条件,系统就会发生死锁,只要上述条件之不一满足,系统就不会发生死锁.
C、处理死锁的方法
由于死锁状态的出现会给整个系统带来严重的后果,所以如何解决死锁问题引起了人们的普遍关注。目前常用的方法有以下三种:
(1)预防死锁
为了使系统中不发生死锁现象,在系统设计初期即选取择一些限制条件,来破坏产生死锁的四个必要条件之一或其中几个。这样,系统中就不会出现死锁现象。这种方法对预防死锁的发生非常有效,但有可能降低系统资源的利用率。
(2)避免死锁
由于一方面预防死锁的方法会降低系统资源利用率,另一方面死锁的必要条件是存在示必就一定会使系统发生死锁,因此为提高系统资源的利用率,可采用避免死锁。避免死锁并不严格限制死锁必要条件的存在,而是在资源的动态分配过程中,使用某种方法去防止系统进入不安全状态,从而避免死锁的紧终出现。
(3)检测和解除死锁
由于死锁产生的概率总是比较小的,所以在一些相对简单的系统中,为节省预防或避免死锁中所增加的系统开销,系统中允许出现死锁状态。在这种系统中,专门设置了一个检测机构,可以随时检测出死锁的发生,并能确定与死锁有关的进程和资源,然后采用适当的方法解除系统中的死锁状态。
常用的解除死锁的方法有两种:一是强制性地撤销一些死锁进程,并剥夺它们的资源给其他的时程;另一种是使用一个有效的挂起和解除挂起机构来挂起一些进程,以便从被挂起进程中剥夺一些资源,用来解除死锁。
预防死锁
(1)打破“请求和保持”条件
打破“请求和保持”条件,即把进程运行中所要求的所有资源在进程开始动行之前,一次性地分配给进程,只要有一种资源不能满足,该进程就必须等待。这样,进程在运行过程中就不再需要新的资源,这种方法又称为预先静态分配法。
(2)打破“不剥夺”条件
打破“不剥夺”条件,即强迫那些请求新资源而没有立即得到满足的进程释放它已保持的其他资源。这意味着一个进程在运行过程可以暂时释放已占有的资源,即允许其他进程剥夺使用该资源,从而破坏了“不剥夺”条件的出现。
(3)打破“环路等待”条件
死锁产生时,一定存在一种进程和资源的循环链。打破“环路等待”条件就是在资源的分配过程中,对资源的请求做出某种限制,使环路不可能出现。
㈥ 优先级反转问题在嵌入式系统中是一中严重的问题,必须给与足够重视。请解释何种情况下需要优先级反转。
优先级翻转 (网络词条http://ke..com/view/2422471.htm 解释的非常到位,摘录如下)更详细请查看:参考视频 http://v.youku.com/v_show/id_XMTAyODU1OTc2.html 第27分30秒左右的视频段。
所谓优先级翻转问题(priority inversion)即当一个高优先级任务通过信号量机制访问共享资源时,该信号量已被一低优先级任务占有,而这个低优先级任务在访问共享资源时可能又被其它一些中等优先级任务抢先,因此造成高优先级任务被许多具有较低优先级任务阻塞,实时性难以得到保证。
例如:有优先级为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运行。
解决优先级翻转问题有优先级天花板(priority
ceiling)和优先级继承(priority inheritance)两种办法。
优先级天花板是当任务申请某资源时, 把该任务的优先级提升到可访问这个资源的所有任务中的最高优先级,
这个优先级称为该资源的优先级天花板。这种方法简单易行, 不必进行复杂的判断, 不管任务是否阻塞了高优先级任务的运行, 只要任务访问共享资源都会提升任务的优先级。
优先级继承是当任务A 申请共享资源S 时,
如果S正在被任务C 使用,通过比较任务C 与自身的优先级,如发现任务C 的优先级小于自身的优先级, 则将任务C的优先级提升到自身的优先级, 任务C 释放资源S 后,再恢复任务C 的原优先级。这种方法只在占有资源的低优先级任务阻塞了高优先级任务时才动态的改变任务的优先级,如果过程较复杂,则需要进行判断。
㈦ 什么是优先级反转+有何危害+如何避免和解决
什么是优先级反转
优先级反转,英文是priority inversion,也有其他叫法:
优先级倒置
优先级逆转
优先级翻转
任务之间谁可以得到执行,是通过任务调度来完成的
2.任务调度有多种方法(算法)
罗宾环调度算法:Round-robin scheling algorithm
基于优先级的调度算法:Priority-controlled scheling algorithm
3.任务调度的一种常见调度算法就是
根据优先级高低去调度,优先让高优先级的任务去执行的
任务调度器,总是去激活某个,在所有任务中优先级是最高的,且处于就绪状态的,任务,即让其去执行
4.任务有多种状态:就绪,挂起,等等
当然,任何任务,都可能由于,需要某种资源,而该资源被别人(别的任务)占用,而无法继续运行下去
此时就变成:挂起 –> 等待其所需要的资源被释放
然后才可以继续变成,就绪,等待下次调度时,就可以继续执行了。
5.任务一般被称为:进程,或更小粒度的线程
此处,均以进程为例来说明
任务调度器,总是去激活某个,在所有任务中优先级是最高的,且处于就绪状态的,任务,即让其去执行
但是,当某个最高优先级的任务A,由于其所需要的某个资源被某个低优先级的任务C占用了(还没使用完,还没释放),所以高优先级任务A就被阻塞了。
此高优先级的任务A,必须等到低优先级任务C,把其所占用的资源释放掉后,才能继续运行。
但是要等到低优先级任务C释放其所占用的资源的话,则很明显,必须要先让低优先级的任务C去执行,等低优先级任务C执行完毕后,才能去释放,高优先级任务A所希望得到的那个资源。
所以,任务调度去,就去调度,让低优先级任务C去执行了。
但是,此时,的问题就来了:
在高优先级任务A执行的这段时间内,某个中优先级的任务B,已经处于就绪状态了。
当高优先级的任务A,由于所需资源被占用而挂起,然后中优先级的任务B,由于比(本来打算去调度执行的)低优先级任务C的优先级高,所以被调度执行,然后B去一直执行,直到结束。
一个具有中等优先级的任务(B),却比一个更高优先级的任务(A)先执行
本来应该是优先级最高的任务A先执行的,结果却变成了,比优先级最高的任务A,的优先级低一些,中等优先级任务B,先执行了。
好像是:高优先级任务A和中优先级任务B,两者之间的优先级调换了,反转了一样。
优先级反转有何危害?
说实话,很久之前,对于:
计算机的概念,都完全只是概念到时候
完全不懂相关技术和概念背后的逻辑的时候
像对于此处的优先级反转,也无法完全理解的时候,自然也不会去考虑此概念背后的含义。
而实际上,不对一个问题背后的现象,原因,去搞清楚的话,自然也是无法理解相关的概念的
(对于,对现实世界中的应用情况不了解,对于概念也理解的不深的话,很可能就会问)
(不就是个优先级反转嘛)即使,发生了优先级反转了,又如何?(地球还不是照转?!)
优先级的反转,有很大危害。
但是,在具体解释优先级反转的危害之前,需要知道相关背景知识:
1.优先级反转,这个概念,往往都是在嵌入式领域内,尤其是嵌入式实时系统方面,才会提及
关于嵌入式实时操作系统,不熟悉的,可以参考:
【整理】嵌入式实时操作系统
2.嵌入式实时操作系统,最最重要的指标就是:确保任务执行时间是可预测的,即涉及到最后期限deadline
要确保,任何时刻,执行某个任务,都不能超过某个时间,比如1ms(我随便举例的)
然后再来解释,优先级反转的危害:
由于优先级反转,造成任务调度时,时间的不确定性。
时间不确定,破坏了实时系统的实时性
严重时可能导致系统崩溃
由于本身基于优先级设计的任务,每个优先级不同的任务,往往对应着实际的现实中的执行的任务
其优先级反转,导致低优先级比高优先级先执行了
直接就导致任务错乱,逻辑错乱了
程序也就异常了?(待确定此部分的理解是否有误)
1.当年火星探路者号(Mars Pathfinder),就由于,此处所说的,优先级反转,而导致了内部执行逻辑出错的bug:
在1997年7月4号发射后,在开始搜集气象数据之后没几天,系统(无故)重启了。
后来,当然,被相关技术人员找到问题根源,就是,这个优先级反转所导致的,然后修复了此bug。
当年火星探路者号用的软硬件是:
硬件:
CPU:RS6000
总线:VME Bus
各种接口卡/外设:
音频
摄像头
1553总线接口
软件:
OS:(Wind River的)VxWorks
What really happened on Mars ?
What really happened on Mars?
如何解决或避免优先级反转?
既然,相对来说,优先级反转,这样的问题,对于,尤其是嵌入式实时系统中,危害这么大,
那么肯定N年前,就有人找到解决办法了:
优先级反转的解决办法:
禁止所有中断(以保护临近区)
当使用,禁止所有中断,来避免优先级反转时,需要满足下面的条件:
可被抢占的
中断已禁止的
由于没有别的第三种的优先级了,所以,也就不可能发生反转了。
(暂时没有完全理解此种的含义。。。。)
priority inheritance 优先级继承:
对于,占了高优先级任务A的某种所需资源的,低优先任务级C,
当A被阻塞,要去调度,即使存在另一个中优先级任务B,则也可以实现:
由于此时低优先级任务C已有和A同样的优先级了,
则调度器自然会去执行:
比中优先级任务B的优先级高的C了。
然后,等C执行完毕后,就可以继续执行A了。
优先级继承的实际例子
What really happened on Mars ?
中为例来来说明如何应用此,优先级继承:
HOW WAS THE PROBLEM CORRECTED?
VxWorks中的mutex对象,添加一个布尔值的参数,表示:
mutex是否使用优先级继承
当mutex初始化时,该参数是关闭的;
当此参数被打开时,低优先级的任务,就从高优先级的任务中继承了相同的优先级,
当然,背后是对应的检测机制:
可以判定出,当然被阻塞的高优先级的任务,所需要的资源,被当前自己这个低优先级任务所占用了
由此,解决了优先级反转的问题,避免了系统再次发生无故重启。
Priority Celling(最高优先级/优先级天花板)
给临界区,即上述的mutex等公用资源的部分
凡是想要用到,临界区的资源的任务,
要进入临界区之前,都将临界区的优先级赋值给该任务,
使得该任务有了最高的优先级,可以不被打断,而始终继续运行,直到用到资源
这样,就避免了,被高优先级A发现某资源被低优先级的C占用之类的问题了
㈧ 什么是操作系统的优先级反转
如果任务之间由于有共享资源出现了竞争或者死锁,是会严重影响系统安全的。因此uC/OS对共享资源提供了保护机制。一般情况下使用的是信号量方法。创建一个信号量并对他进行初始化,当一个任务需要使用一个共享资源时,他必须先申请得到这个信号量。在这个过程中即使有优先权更高的任务进入了就绪态,因为无法得到信号量,也不能使用该资源。在uC/OS中称为优先级反转。简单地说,就是高优先级任务必须等待低优先级任务的完成。