做分类信息网站赚钱吗,今天出京入京最新通知,企业如何进行网站建设,贵阳网站制作公司这是转发宋老师写的文章#xff0c;我也是刚知道#xff0c;宋老师跟我一样也是养娃的人了#xff0c;国庆期间#xff0c;看看文章#xff0c;看看升升国旗。很久没有写技术文章了#xff0c;做码农难#xff0c;做养娃的码农更难#xff0c;趁着娃看动画片的机会我也是刚知道宋老师跟我一样也是养娃的人了国庆期间看看文章看看升升国旗。很久没有写技术文章了做码农难做养娃的码农更难趁着娃看动画片的机会受着王菲童鞋《我和我的祖国》歌唱精神的鼓舞我要来说几句。硬实时是什么众所周知硬实时的概念不是越快越好而是强调可重复的repeatable、决定性的时间期限内给予响应deterministic response time。所以它的本质点是可预期实时系统的计算正确性不仅取决于计算的逻辑正确性还取决于产生结果的时间。比如汽车碰撞后必须在X时间内弹开安全气囊你弹开晚了人已经挂了。当然最恶劣场景下的延迟可能作为一个时间参数来评估RTOS本身的性能指标。比如你改造了Linux实现了中断或高优先级任务的100us以内的确定性延迟但是RT-Thread可能不改造就可以到达us以内的延迟。那么你延迟要求只需要200us以内的你选改造后的Linux也没有什么毛病但是如果你要的就是us级那么对不起Linux不是你的菜。众所周知RT-Thread、FreeRTOS、VxWorks这样的操作系统是硬实时的Linux这样的操作系统是提供软实时能力的针对的 miss 掉截止期限也死不了人的那种应用比如看电影。那么这个时候我们诞生了一个疑问是不是在RTOS里面随便写代码都能满足硬实时而在Linux里面无论怎么写代码都满足不了硬实时我认为这2个问题的答案都是否定的。Linux为什么不硬实时?我们首先看一下Linux为什么不能提供硬实时能力。我们认为Linux主要有如下问题你站在硬实时的角度看它是问题你换个角度看它就反而是正确的地方。1. spinlock是一个随处可见被内核、驱动使用的APILinux内核和驱动程序员钟爱spinlock到了如痴如狂的程度可以说不睡眠、时间较短的critical section场景都会第一时间想到spinlock。平生不识自旋锁就称英雄也枉然。自旋锁的优越性在于在2个人这2个人可能是线程与线程、中断与线程、中断与中断等竞争一个锁的时候避免失败的那一方切换上下文context所以与其上下文切换不如原地等。但是自旋锁本身也引起了副作用它引起了持有锁的CPU核的抢占调度的禁止。内核自旋锁的实现更多的是核间自旋转而核内是通过禁止抢占来实现临界区保护的。假设T1, T2, T3, T4运行在一个核上面当T1拿到spinlock后这个核上的抢占调度被禁止如果在T1持有spinlock的时间内T2是一个高优先级的实时任务尽管T2被唤醒它也不可能立即打断T1的执行必须等待T1释放spinlock。由于T1究竟会持有 spinlock 多久做xxxx这个鬼都不知道所以T2究竟要等多久也未可知这显然破坏了决定性的时延。2. Linux的中断执行时间可能过长且不可嵌套众所周知早期的Linux版本有个标记叫IRQF_DISABLED标记本中断在执行的时候其他所有中断都被禁止进入而后Linux内核实际去掉了这个申请flags其实就是都是IRQF_DISABLED了总体可认为Linux内核不支持中断的嵌套。int request_irq(unsigned int irq, irq_handler_t handler, unsigned long irqflags, const char *devname, void *dev_id);中断在执行的时候所有的中断都进不来这个设计本身简化了内核但是对于硬实时的打击是致命的前面的中断不执行完成优先级再高的中断也得给我等着。比如中断1在执行的过程中来了中断2而中断2对应的事情是必须要决定性时延的由于IRQ1的中断服务程序也是码农写的我们无法确定这个中断服务程序要执行多久。这显然让高优先级中断2的进入延迟不再具备可预期性。3.软中断(softirq)是一个比进程上下文优先级更高的上下文我们设想一个场景哪怕Linux解决了问题2就是Linux的中断变地可嵌套高优先级的中断可以打断低优先级的中断并且高优先级的中断2唤醒了一个用户写的实时线程。IRQ2唤醒了实时任务T1但是T1必须等待IRQ1唤起的软中断(也包括使用软中断上下文的tasklet等)被执行完T1才能投入执行。IRQ1唤起的softirq的代码是码农写的这个码农写多久鬼都不知道这显然破坏了实时任务T1得以调度执行的确定性时延。4. 内核里面会屏蔽中断的API如local_irq_disable、spin_lock_irqsave等前面笔者已经反复强调过在驱动程序里面调用local_irq_disable()通常都是一个bug因为它无法修复另外一个核上运行的线程、中断服务程序与本核线程之间的竞争。尽管在单核处理器里面调用这个API是通常安全的但是我们哪怕是在单核编程都要假装自己是多核的样子这个是在Linux里面写代码跨平台的最基本常识。相信绝大多数童鞋都不会傻到写驱动的时候再去调local_irq_disable这样的API。但是spin_lock_irqsave这样的API在内核的使用可以说太常见了它其实是适用于一个经典的场景就是中断服务程序与线程之间有竞态的情况。作为一个内核程序员相信如下的经典用法你已经熟悉地不能再熟悉满满地都是套路:它把T1、T2、T3、T4、IRQ1、IRQ2这6者之间的竞争消灭于无形。T1如果持有了spin_lock_irqsave本核上的T2、IRQ1显然进不来CPU1上面的T3、T4、IRQ2想访问T1访问的临界资源必须spin。IRQ1如果持有了spin_lock CPU1上面的T3、T4、IRQ2想访问IRQ1访问的临界资源必须spin。那么问题又来了spin_lock_irqsave既屏蔽了抢占又屏蔽了中断这会导致中断和实时任务的确定性时延造成不可预期的破坏。因为spin_lock_irqsave 和 spin_lock_irqrestore是码农写的鬼都不知道它要多久。当然历史上粗犷的大内核锁Big Kernel LockBKL也是一个问题。由于晶晶姑娘不喜欢内核粗犷的一面BKL在如今的内核里面已经烟消云散。在Linux的世界里这些锁当然都没有一个锁牛逼就是RCU尤其是面对这个世界符合阿姆达尔定律Amdahls law定律的情况下我们既要保证临界资源访问的被保护又要尽一切可能地让多个线程同时狂奔。关于RCU的细节谢神医已经有多篇文章论述。Linux的世界大概是这样的:中断、软中断、线程包括ksoftirqd线程。我们都清楚地知道软中断大量陷入的情况下内核会将后续的软中断投入ksoftirqd内核线程执行所以软中断还有一个可能的执行时机是在内核线程里面。5. Linux用户空间内存的lazy分配机制与交换swap对于喜欢在RTOS写程序的童鞋来说Linux的世界一时半会难以理解但是对于写Linux的童鞋来说绝大多数的RTOS简直就是在裸奔。我们都知道在Linux里面用户空间的内存都执行lazy的分配机制。比如你malloc一个内存char *p malloc(1024*1024);这个时候Linux忽悠你说拿到了内存并且p获得了地址但是实际的拿到却是在你写的时候以page fault缺页中断的形式获得的。比如你写p[0]1就拿到了第一页你写p[4096]就拿到了第2页。这个lazy的分配机制也同样适用于栈、代码段等。你是一个实时的线程你被唤醒得以执行你执行的时候发现你访问的临时变量还没有获得内核你的代码段可能还特马在硬盘里请问你实时个什么鬼你执行到函数b的时候去访问d[1000]结果发现这个栈的这页内存还要通过page fault来通过内核buddy去申请你的确定性延迟还如何满足main()
{ … a();
}
a()
{ … b();
}
b()
{ int d[1024]; d[1000]100; c();
}当然已经进入内存的东西也由于内核的swap机制会与磁盘进行交换。绝大多数的RTOS都没有这个“问题”这也恰恰是他们不够“牛逼”的地方。对于手机、电脑这种富应用的系统而言你不能用资源已经被确定性分配的思维模式来思考。Linux preempt-rt如何解决这些问题?前段时间这篇文章刷屏了《到今天为止ARCH_SUPPORTS_RT谁他么都不是真barrybarryUbuntu:~/develop/linux$ git grep ARCH_SUPPORTS_RTarch/Kconfig:config ARCH_SUPPORTS_RTkernel/Kconfig.preempt: depends on EXPERT ARCH_SUPPORTS_RT所以你要真地在mainline见到PREEMPT_RT开花结果还必须活地更久一点。当提到 preempt-rt 补丁的时候我必须强调一点Linux不是一个裸奔的操作系统。Linux 的应用都是在用户空间写的一个个进程、线程。所以相对于其他 RTOS 可能更加强调高优先级中断的确定性时延RTOS不太特别强调机制与策略分离的概念整个东西编译在一起的话在中断里面放策略也未尝不可在Linux时间里用户空间高优先级的 RT 线程的确定性调度时延就显得更加critical因为Linux内核里面你不能裸奔地把用户策略的东西放进内核内核提供的是一些操作接口而已简单来说你要做的事情是一个应用而应用是个用户空间的东西。风在吼马在叫娃儿在咆哮。今天就谈到这里明天接着谈。我相信你还有很多的疑惑比如很多童鞋说你刚才提到的Linux的一些硬实时的毛病在 RTOS 里面其实也都有我会给你一个交代。扫码或长按关注回复「 加群 」进入技术群聊