目录
我看了很多博客,阅读量最多的也详细介绍了这两个系统,但我对这个操作系统的界限还是模糊的(当然我知道Linux,它更强大)。我想要的答案是为什么在Linux如此强大的情况下,RTOS仍然有一席之地。我认为这是它们之间的主要区别。查阅了资料后,我想我得到了答案
区别
你能说Linux和RTOS的区别就在于Linux更强大,支持内存管理,文件系统,网络等吗?如果是这样,我为什么需要RTOS?我觉得实时和非实时是这两者最本质的区别。
实时操作系统
又称实时操作系统,按顺序运行,管理系统资源,为开发应用程序提供一致的基础。与一般操作系统相比,实时操作系统最大的特点就是“实时”。如果有任务需要执行,实时操作系统会立即(短时间内)执行任务,不会有长时间的延迟。这一特点保证了每项任务的及时执行。(而Linux则是在保证系统性能的情况下,尽可能快地处理任务)
关于实时操作系统人们常见一些误解,比如:速度快、吞吐量高、代码简洁、代码体积小等等,其实这些都不是实时操作系统的特点,其他操作系统也可以做到这一点。
只有“实时”才是RTOS的最大特点,其他都不是。(而且好的实时系统往往在保持良好性能的同时,牺牲了系统的吞吐量)
实时操作系统必然包含实时任务调度器,该任务调度器与其他操作系统最大的不同在于强调:严格按照优先级分配CPU时间,时间片轮换不是实时调度器的必要选项。
实时操作系统的理念至少可以解决两个问题:一是早期CPU任务切换的开销过高,而实时调度器可以避免频繁任务切换带来的CPU时间的浪费;二是在一些特殊的应用场景下,需要保证重要的任务优先执行。
简单来说,任务之间的切换应该基于优先级。只有具有有限服务模式的 RTOS 才是真正的实时操作系统。具有时间分片和协作模式的 RTOS 不是真正的“实时”。
Linux为什么不能被称为实时操作系统?
Linux操作系统从2.5版本开始进行了改进,使进程具有可抢占性,但是Linux无法保证可预测性和确定性。Linux中最大的问题之一就是优先级反转现象。例如,当低优先级的进程处于临界区时,高优先级的进程必须等待低优先级的进程;或者,当低优先级的中断服务进程正在运行时,高优先级的进程必须等待。这种现象会造成很大的不确定性。另外,Linux使用了自旋锁。自旋锁会导致进程不断循环,持续占用CPU资源。在多核处理器上,这会导致某个核上的进程无缘无故地停止等待。
值得一提的是,虽然在Linux中也存在优先级调度,但是在Linux中高优先级的并不一定能先运行,Linux中任务的优先级是会发生变化的,如下所述:
我们一般把经常等待的线程称为IO密集型线程,很少等待的线程称为CPU密集型线程。IO密集型线程总是比CPU密集型线程更容易获得优先级的提升。
在优先级调度下,有一种现象叫做饥饿。当一个线程的优先级较低,而它之前总是有更高优先级的任务要执行,导致它无法执行时,就会发生饥饿。为了避免饥饿,调度系统通常会逐渐提高那些等待时间过长而无法执行的线程的优先级。
所以Linux的实时性能虽然有所提高,但是它并不是一个实时操作系统。
总结
实时操作系统设计以实时性为核心,高优先级的任务会优先执行。实时操作系统的主要目标是创建一个可预测、确定性的环境。我对这句话的理解是,所有任务从被创建那一刻起都是可预测的,比如必须在截止期限内返回结果。实时操作系统可以确保提前知道完成计算的最坏时间,并且完成计算的时间不会超过该限制。因此,可预测性和确定性是实时操作系统最突出的特征。
它并不是一个实时操作系统,而是以确保系统性能为前提而设计的。
例如:
非实时操作系统在 99.9% 的情况下可能需要 250 微秒才能完成计算任务,但在 0.1% 的情况下可能需要 2 毫秒才能完成。这对于实时操作系统来说是不可接受的。
最后,还有一件事
RT-Linux相对于Linux而言,在实时性方面做出了改进,它在Linux的基础上提出一个RT补丁,并将其添加到Linux中,使Linux完善为实时操作系统。
其主要任务是改进Linux的优先级反转、自旋锁等问题,以满足实时操作系统的要求。
线程中断
主要解决中断处理带来的优先级反转问题,在Linux正常的中断请求处理中,硬件中断等设备服务可能会造成所有任务的较大延迟。
RT-Linux 的改进是当设备驱动提交 IRQ 时,会产生一个线程来服务该中断请求。每个中断请求对应一个线程。当某个线程正在服务中断请求时,中断线会被阻塞,不再接收中断请求。该线程会执行以下操作:
while(!kthread_should_stop())
{
set_current_state(TASK_INTERRUPTIBLE);
do_hardirq(desc);
//让出cpu
cond_resched();
//进程调度
schedule();
}
此时中断虽然没有被处理,但是因为中断线已经被屏蔽,所以不会再触发中断,当中断线程被调度时,才会处理中断。这样中断产生的优先级反转时间就缩短为屏蔽中断线+唤醒中断线程。当然这种改进只是针对部分中断,并不是所有中断。
说到中断,这里有个知识点要记录一下,现在的Linux版本已经不支持中断嵌套了,这里的中断嵌套指的是中断的上半部分,因为当执行到中断的上半部分时,所有的中断都会被阻塞(这也是实时性无法保证的原因之一)
睡眠自旋锁
自旋锁可能会造成大量的资源浪费,产生不确定性。RT-Linux 的改进是将自旋锁替换为休眠自旋锁(信号量)(当然,这种情况下,你得注意中断)。这样,如果一个线程在另一个进程正在访问临界区时试图访问它,它将被调度出去,进入休眠状态,直到该进程释放临界区。
当然这种替代并不彻底,有些情况下还是会使用自旋锁,比如当切换进程的代价大于等待的代价时。
优先级继承
Linux 还可能造成无限优先级反转。比如有三个进程:A(高优先级)、B(中优先级)、C(低优先级)。首先进程 C 开始执行,然后进程 A 抢占并开始执行。此时进程 A 需要访问进程 C 持有的某个资源,于是进程 A 休眠,进程 C 继续执行。此时进程 B 抢占 CPU 开始执行。问题在于优先级最高的进程 A 会一直休眠,直到进程 B 执行完毕,进程 C 执行完毕并释放资源。这样可能造成无限的停止等待。
RT-Linux 在这方面的改进是使用优先级继承。当一个线程阻塞在某个资源上,而这个资源又被一个低优先级的线程持有时,低优先级的线程就会继承被阻塞线程的优先级。这样,低优先级的线程就不会被其他低优先级的线程抢占,从而大大减少优先级反转的时间。(当然,这显然不是一个彻底的解决方案,毕竟进程 C 还是会先于进程 A 执行)
后记(2022 年 4 月 9 日添加)硬实时
... 硬实时进程具有严格的时间约束。某些任务必须在指定的时间限制内完成。如果飞机的飞行控制命令由计算机处理,则必须尽快处理和发送这些命令,即保证在一定时间内完成。例如,如果飞机正在着陆,飞行员想要拉起机头。如果计算机在几秒钟后发送命令,它将毫无用处!此时,唯一需要考虑的就是飞机的结局——俯冲到地面。硬实时进程的关键特性是它们必须在保证的时间范围内处理。请注意,这并不意味着所需的时间范围特别短,而是系统必须保证即使在不可能或不利的情况下也不会超过一定的时间范围。
Liunx 支持硬实时吗?
Linux 不支持硬实时处理,至少在主流内核中不支持。但是,有一些修改版本(例如 、 和 RATI)提供了此功能。在这些修改版本中,Linux 内核作为单独的“进程”运行,以处理不太重要的软件,实时工作在内核之外完成。内核仅在没有实时关键操作要执行时才会运行。
扫一扫在手机端查看
我们凭借多年的网站建设经验,坚持以“帮助中小企业实现网络营销化”为宗旨,累计为4000多家客户提供品质建站服务,得到了客户的一致好评。如果您有网站建设、网站改版、域名注册、主机空间、手机网站建设、网站备案等方面的需求,请立即点击咨询我们或拨打咨询热线: 13761152229,我们会详细为你一一解答你心中的疑难。