随手记——Linux中编写实时性代码时需要注意哪些问题

Posted 穿越临界点

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了随手记——Linux中编写实时性代码时需要注意哪些问题相关的知识,希望对你有一定的参考价值。

在学习资料满天飞的大环境下,知识变得非常零散,体系化的知识并不多,这就导致很多人每天都努力学习到感动自己,最终却收效甚微,甚至放弃学习。我的使命就是过滤掉大量的无效信息,将知识体系化,以短平快的方式直达问题本质,把大家从大海捞针的痛苦中解脱出来。

1 什么是实时性

实时并不等价于运行速度非常快,因为快也是相对的。

实时确切的含义是时间可控。

2 实时性场景分析

什么时候需要考虑实时性?

这个问题甚至比如何实现实时性更加重要。因为如果你知道了某个模块具有实时性约束你再去研究它就变得比较专注,总是会攻克它的。但是,如果你连敌人是谁都不知道,这就很麻烦了。本小节就是来解决这个问题。

接下来,根据遇到的两个真实场景进行说明。

2.1 调用别人的函数时

这种场景还是比较简单的,一般都会注意到。

如果自己编写的函数有实时性要求,在调用别人的函数时就要比较谨慎了。如果能看到别人的函数实现当然最好了,就可以根据我们下面介绍的规则和方法来确认该函数是否具有实时性;如果不能就比较槽糕了,此时,必须要联系该模块负责人来进行确认,必要时和他(她)一同查看源码。

我在工作中就遇到这样一个问题,在一个很少进入的代码流程中调用了别的部门实现的一个函数,导致我们的代码偶现地运行超过预期时长。最后通过时间打点(在Linux下如何测试代码执行时间)发现是该函数的问题后联系该部门负责人一起查看源码,发现该函数实现中有睡眠行为。而该函数实现其实并不需要睡眠。这倒是其次,该函数最大的问题就是没有声明自己是有可能进入休眠的,提示调用者在编写实时性代码时不要使用该函数。

2.2 被别人的函数调用时

这种场景才是最坑人的,隐蔽性极强,尤其是跨部门的时候。

我就在工作中遇到过一次,调试了两周,拉通了多个部门才发现是实时性的问题。是的,一开始,你根本都意识不到是实时性的问题。

我还原一下当时的场景问题定位的大体过程,大家来一起感受感受。我们做代码重构,改动量还是比较大的。开始一段时间的测试都没有出现问题,但是,某一天“东窗事发”了,业务上偶现地开始出现问题。首先从出现问题的业务A处开始定位,然后牵扯到业务B,最后又带出业务C,负责业务C的同事说他们的某个函数没有在规定的时间内运行完——到这里才引出了实时性问题——但定位到这里我们已经花费了一周多的时间了。然后,进行时间打点,最终跟踪到我们修改的一个函数——将之前的忙等(死等)修改成了睡眠等待,从而导致了运行时间变长的恶果。

我们来反省一下这个小小的修改为什么会造成这么重大的业务问题。这其实已经超出了技术范畴了,根本原因是管理的不够规范——业务模块之间隔离太严重,而且没有清晰的接口说明,这直接导致了我不知道自己修改的函数居然是运行在有实时性要求的函数中的;负责业务C的同事一开始居然也没有意识到他们的函数运行是有实时性要求的。

退一步讲,如果我在改这个函数的时候能意识到改成睡眠等待可能会影响该函数的运行时长的话,我能否避免这个问题产生呢?这个还是比较难的。因为我需要发邮件周知所有部门去询问谁调用了我的函数,调用我的函数的模块是否有实时性要求。人家的反应要么是不理会,要么就是让你别瞎折腾。

所以,已经存在的函数如果确定别的部门有调用,尽量不要修改。如果是新增函数接口,写清楚(是否会导致阻塞或睡眠)是否支持实时性要求。

3 编写实时性代码需要注意的问题

接下来讨论一些我们可控的细节问题——编写实时性代码需要注意的问题。

编写中断处理函数时需要注意的问题是本论题的一个子集,其中的规则和方法可以迁移到这里。

3.1 谨防阻塞

阻塞造成的时间推迟可长可短,没有严格意义上的确定性,因此要谨慎使用;在硬中断处理函数中绝对不要使用。

可能造成阻塞的接口或机制有:malloc、锁、调度程序、sleep、select/poll/epoll等。

3.2 控制延时

将其与阻塞分开的原因是,此处讨论的延时有一个特点,就是延迟的时间是可以测量的,可以使用时间打点函数进行测量;能够测量就比较好控制,但使用时还是需要主要以下几点:

  • 尽量不要写死循环,因为一旦死循环跳出条件(比如读取外围芯片的一个状态)长时间不成立或者永远不成立,该线程就会卡住不动了。
  • 不要任意地使用忙等,而且还等很长时间。这种代码不但影响自身所在函数的运行效率,还会影响所在线程内的其他事件或消息的处理效率。
  • 谨慎使用 for+usleep 这种延时方式,因为在心跳比较慢的处理器和系统上usleep很短的时间是会失效的,然后就会演变成死循环。

4 总结

好多细节没有必要记忆,工作中踩了坑自然就会记住,而且记得死死的。

所以,我希望的是,看完这篇文章后,你再写代码时能够默默问自己一句——我考虑实时性了么?


恭喜你又坚持看完了一篇博客,又进步了一点点!如果感觉还不错就点个赞再走吧,你的点赞和关注将是我持续输出的哒哒哒动力~~

以上是关于随手记——Linux中编写实时性代码时需要注意哪些问题的主要内容,如果未能解决你的问题,请参考以下文章

随手记——在Linux下如何测试代码执行时间

随手记——在Linux下如何测试代码执行时间

随手记——栈空间使用率实时监测工具

随手记——栈空间使用率实时监测工具

Android开发随手记

2019-3-19记随手记面试