看了不少博客,浏览量最多的也是详细的介绍了这两种系统,可我对这种操作系统的界限还是很模糊(当然我知道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密集型线程,而把很少等待的线程称为CPU密集型线程, IO密集型线程总是比CPU密集型线程容易得到优先级的提升。
在优先级调度下,存在一种饿死的现象,一个线程被饿死,是说的优先较低,在它执行前总有比它优先级高的任务要执行,导致它无法执行。为了避免饿死现象,调度系统常常会逐步提升那些等待了过长时间的得不到执行的线程的优先级。

所以虽然linux的实时性有所提高,但它并不是实时操作系统

总结

实时操作系统设计以实时性为前提进行设计,高优先级任务一定会优先执行。实时操作系统的主要目标是创造一个可预见的、确定的环境。我对这句话的理解是,所有的任务从它被创建开始它就是可预见的,比如它必须在截止时间内返回结果。一个实时操作系统可以保证完成计算的最坏情况下的时间是预先已知的,并且完成计算的时间不会超过限制。所以可预见性和确定性是实时操作系统最突出的特点。
而非实时操作系统以保证系统性能为前提进行设计。
举个例子
一个非实时操作系统完成一个计算任务在99.9%的情况下需要250微秒,但在0.1%的情况下需要2毫秒才能完成。这对实时操作系统而言是不可接受的。

最后再提一点

相比于Linux, RT-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不支持硬实时处理, 至少在主流的内核中不支持。 但有一些修改版本如RTLinux、 Xenomai、 RATI提供了该特性。 在这些修改后的方案中, Linux内核作为独立的“进程”运行来处理次重要的软件, 而实时的工作则在内核外部完成。 只有当没有实时的关键操作执行时, 内核才会运行。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐