当前位置:网站首页>嵌入式环境下并发控制与线程安全
嵌入式环境下并发控制与线程安全
2022-07-30 11:27:00 【李肖遥】
关注、星标公众号,直达精彩内容
来源:网络素材
代码规模日益增大和基于RTOS的多线程技术使嵌入式软件开发越来越关注“并发控制和线程安全”,当多个执行线程(指正在运行代码的任意上下文,包括线程和中断服务程序)需要访问相同的共享资源时(包括软件数据和硬件资源),就可能因为竞态而导致错误。
这种错误容易制造,但很难找到,从设计上保证正确性收益更大。
竞态的产生
当一个共享资源被多个执行线程“非原子性”访问时,一个执行线程的操作被另一个执行线程打断而带来错误就叫“竞态”,共享资源包括硬件设备和软件实体。
最明显的共享是全局变量,如果定义如下数组,它被多个线程读和写,这将成为最易理解的竞态。
int g_aiGlobalBuf[100];另一种不太明显的共享是由不可重入函数造成的,如果多个线程调用了下面的函数,那么同样产生竞态。
void ProcGlobalBuf(int iPos, int iVal)
{
g_aiGlobalBuf[iPos] = iVal;
}硬件资源被多个线程使用也会引入竞态,如下面的函数(使用伪代码)被2个线程同时调用,那么第一个线程的数据可能还没有发送完毕就被第二个线程的数据“覆盖”。
void SendByDMA(const void *p_vBuf, int iSize)
{
DMA.StartAddr = p_vBuf;
DMA.Count = iSize;
EnableDMA();
}一句话:任何被多个执行线程使用的资源都可能产生“竞态”。
并发控制规则
规则一:只要可能,就应该避免资源的共享。
如果没有并发访问,就不会有竞态的产生。因此,设计代码应该具有最少的共享。这种思想的最明显应用是避免使用全局变量。如果我们将资源放在多个执行线程都会找到的地方,则必须有足够的理由。
例如硬件资源的分配中,串口只能由线程1调用,网口只能由线程2调用,LCD只能由线程3调用,那么这3种硬件资源的竞态一开始就杜绝了,同理可以应用到软件资源上。
规则二:引发竞态的共享资源必须加锁
然而,在计算机的世界里共享就是现实的生活,在单个执行线程之外共享硬件或软件资源的任何时候,因为另外一个线程可能产生对该资源的不一致观察,就必须显示地管理对该资源的访问。
像只读数据(如芯片的序列号)对于任何访问它的执行线程看来都是一致的,那么竞态是不可能发生的。
基于RTOS的嵌入式环境下对共享资源的加锁一般有3种途径:关中断、使用信号量、禁止任务切换。
关中断应用于2种情况:如果任务代码和中断程序共享资源,或者共享资源访问时间很短(如操作一个变量);如果仅线程之间访问一些共享资源且操作时间不太长,禁止任务切换可以胜任;其他情况下都将使用信号量。
规则三:被多线程调用的函数必须是可重入
一个函数是否是可重入的判断规则:
一个可重入函数一般用原子的方法使用变量,除非这些变量存储在调用这个函数的堆栈中或这些变量是任务的私有变量。
一个可重入函数一般不调用其他的不可重入的函数。
一个可重入函数一般不用非原子的方法使用硬件。
锁的使用规则
当我们创建一个可被并行访问的对象时,应该同时定义用来控制访问的锁。锁定模式必须在一开始就安排好,否则其后的改进将会非常困难。
如果某个获得锁的函数要调用其他同样试图获取这个锁的函数,我们的代码就会死锁,即不允许锁拥有者第二次获得这个锁;如果试图这么做,系统将持起。
提供给外部调用的函数必须显示地处理锁定,在编写那些假定调用者已处理了锁定的内部函数时,我们自己应该显示地说明这种假定,否则几个月后再回头来看这些代码时,很难记清在调用某个特定函数时是否需要拥有锁。
尽可能避免出现需要多个锁的情况,实在需要多个锁就要防止死锁的发生:始终以相同的顺序获得锁,并且了解其他代码操作锁的做法;先获取自己局部锁,再获取其他锁;在拥有锁时尽量避免线程被挂起,那样会导致实时性下降,甚至永久性挂起系统。
原文链接:https://blog.csdn.net/jiangjunjie_2005/article/details/30713585
版权声明:本文来源网络,免费传达知识,版权归原作者所有。如涉及作品版权问题,请联系我进行删除。
‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧ END ‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧
关注我的微信公众号,回复“加群”按规则加入技术交流群。点击“阅读原文”查看更多分享,欢迎点分享、收藏、点赞、在看。边栏推荐
- win下怎么搭建php环境的方法教程
- Transfer Learning Technology Training
- 时间序列曲线相似性
- 反转链表-递归反转法
- C# 枚举类型 于xaml 中区别
- Differences between lock spin and mutex usage scenarios
- Based on the analysis of the acoustic channel cable tunnel positioning technology
- 自定义查询--关于倒排索引的研究
- 久经沙场的程序员居然也被某鱼的假程序员骗了,程序员之间的信任应该是最高的,他一个人毁了这种信任感
- 明德扬FPGA开发板XILINX-K7核心板Kintex7 XC7K325 410T工业级
猜你喜欢

明德扬FPGA开发板XILINX-K7核心板Kintex7 XC7K325 410T工业级

活动速递| Apache Doris 性能优化实战系列直播课程初公开,诚邀您来参加!

优酷VIP会员周卡只需7.5元,看《沉香如屑》用优酷视频

HJY-F931A/YJ three-phase voltage relay

I built another wheel: GrpcGateway

Performance testing of API Gateway APISIX on Google Cloud T2A and T2D

Manage reading notes upward

Horizontal comparison of 5 commonly used registration centers, whether it is used for interviews or technical selection, is very helpful

高能产出!腾讯内部的MyCat中间件手册,理论实操齐下

EA中的业务对象和业务实体你分得清吗?
随机推荐
stm32 RTC闹钟唤醒低功耗模式
English line break
定制.NET 6.0的依赖注入
Taobao/Tmall taobao comments q&a list interface API
C language - bitwise operations
EA中的业务对象和业务实体你分得清吗?
京东校招笔试题+知识点总结
PanGu-Coder: Function-level code generation model
云原生应用的概念和云原生应用的 15 个特征
Summary of text alignment, line height, space, etc.
基于.NetCore开发博客项目 StarBlog - (16) 一些新功能 (监控/统计/配置/初始化)
Horizontal comparison of 5 commonly used registration centers, whether it is used for interviews or technical selection, is very helpful
牛客-TOP101-BM42
AIX shell获取前几个月时间
基于多目标两阶段随机规划方法的电热联合系统调度
深入浅出零钱兑换问题——背包问题的套壳
Underwater target detection method based on spatial feature selection
LeetCode_235_Last Common Ancestor of Binary Search Tree
LeetCode_236_二叉树的最近公共祖先
LeetCode_236_Last Common Ancestor of a Binary Tree
