良许Linux教程网 干货合集 嵌入式环境下并发控制与线程安全

嵌入式环境下并发控制与线程安全

代码规模的增大以及基于实时操作系统(RTOS)的多线程技术使得嵌入式软件开发越来越注重”并发控制和线程安全”。当多个执行线程(包括线程和中断服务程序)需要访问相同的共享资源时(无论是软件数据还是硬件资源),竞争条件可能会导致错误的发生。

竞争条件的错误往往难以察觉,因此在设计阶段保证正确性的收益更为显著。

竞态条件的产生

当一个共享资源被多个执行线程以非原子操作的方式访问时,一个线程的操作可能会被另一个线程打断,从而引发错误。共享资源可以是硬件设备或软件实体。

一个最明显的共享资源是全局变量。例如,如果定义了以下数组,而多个线程对其进行读写操作,就会产生最容易理解的竞态条件。

int g_aiGlobalBuf[100];

另一种不太明显的共享情况是由于不可重入函数的使用而引起的。如果多个线程调用了以下函数,同样会产生竞态条件。

void ProcGlobalBuf(int iPos, int iVal)
{
  g_aiGlobalBuf[iPos] = iVal;
}

同时,当多个线程同时调用以下函数(伪代码),使用硬件资源时也会引入竞态条件。在这种情况下,第一个线程的数据可能还没有发送完成就被第二个线程的数据所覆盖。

void SendByDMA(const void *p_vBuf, int iSize)
{
    DMA.StartAddr = p_vBuf;
    DMA.Count = iSize;
    EnableDMA();
}

简而言之,任何被多个执行线程使用的资源都有可能产生竞态条件。

并发控制规则

规则一:只要可能,就应该避免资源的共享。

如果没有并发访问,就不会有竞态的产生。因此,设计代码应该具有最少的共享。这种思想的最明显应用是避免使用全局变量。如果我们将资源放在多个执行线程都会找到的地方,则必须有足够的理由。

例如硬件资源的分配中,串口只能由线程1调用,网口只能由线程2调用,LCD只能由线程3调用,那么这3种硬件资源的竞态一开始就杜绝了,同理可以应用到软件资源上。

规则二:引发竞态的共享资源必须加锁

然而,在计算机的世界里共享就是现实的生活,在单个执行线程之外共享硬件或软件资源的任何时候,因为另外一个线程可能产生对该资源的不一致观察,就必须显示地管理对该资源的访问。

像只读数据(如芯片的序列号)对于任何访问它的执行线程看来都是一致的,那么竞态是不可能发生的。

基于RTOS的嵌入式环境下对共享资源的加锁一般有3种途径:关中断、使用信号量、禁止任务切换。

关中断应用于2种情况:如果任务代码和中断程序共享资源,或者共享资源访问时间很短(如操作一个变量);如果仅线程之间访问一些共享资源且操作时间不太长,禁止任务切换可以胜任;其他情况下都将使用信号量。

规则三:被多线程调用的函数必须是可重入

一个函数是否是可重入的判断规则:

一个可重入函数一般用原子的方法使用变量,除非这些变量存储在调用这个函数的堆栈中或这些变量是任务的私有变量。

一个可重入函数一般不调用其他的不可重入的函数。

一个可重入函数一般不用非原子的方法使用硬件。

锁的使用规则

当我们创建一个可被并行访问的对象时,应该同时定义用来控制访问的锁。锁定模式必须在一开始就安排好,否则其后的改进将会非常困难。

如果某个获得锁的函数要调用其他同样试图获取这个锁的函数,我们的代码就会死锁,即不允许锁拥有者第二次获得这个锁;如果试图这么做,系统将持起。

提供给外部调用的函数必须显示地处理锁定,在编写那些假定调用者已处理了锁定的内部函数时,我们自己应该显示地说明这种假定,否则几个月后再回头来看这些代码时,很难记清在调用某个特定函数时是否需要拥有锁。

尽可能避免出现需要多个锁的情况,实在需要多个锁就要防止死锁的发生:始终以相同的顺序获得锁,并且了解其他代码操作锁的做法;先获取自己局部锁,再获取其他锁;在拥有锁时尽量避免线程被挂起,那样会导致实时性下降,甚至永久性挂起系统。

以上就是良许教程网为各位朋友分享的Linu系统相关内容。想要了解更多Linux相关知识记得关注公众号“良许Linux”,或扫描下方二维码进行关注,更多干货等着你 !

137e00002230ad9f26e78-265x300
本文由 良许Linux教程网 发布,可自由转载、引用,但需署名作者且注明文章出处。如转载至微信公众号,请在文末添加作者公众号二维码。
良许

作者: 良许

良许,世界500强企业Linux开发工程师,公众号【良许Linux】的作者,全网拥有超30W粉丝。个人标签:创业者,CSDN学院讲师,副业达人,流量玩家,摄影爱好者。
上一篇
下一篇

发表评论

联系我们

联系我们

公众号:良许Linux

在线咨询: QQ交谈

邮箱: yychuyu@163.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

关注微博
返回顶部