首页 > 代码库 > 位域结构体多线程访问出错的问题分析
位域结构体多线程访问出错的问题分析
位域结构体能节省一些内存空间,但是使用不当会产生race conditions,导致程序异常,下面简要分析错误产生的原因和解决方案。
首先定义一个简单的bit field结构体。
+struct bit_filed {+ unsigned a : 1;+ unsigned b : 1;+ unsigned c : 1;+ unsigned d : 1;+ unsigned e : 1;+ unsigned f : 1;+ unsigned g : 1;+ unsigned h : 1;+} val;+++int test_bitfield1(void)+{+ val.a = 1;+ return 0;+}++int test_bitfield2(void)+{+ val.b = 1;+ return 0;+}
然后反汇编
ffffffc0005421e8 <test_bitfield1>:ffffffc0005421e8: f0000fa1 adrp x1, ffffffc000739000 <__hyp_idmap_text_end+0x4800>ffffffc0005421ec: f9426821 ldr x1, [x1,#1232]ffffffc0005421f0: 52800000 mov w0, #0x0 // #0ffffffc0005421f4: 39400022 ldrb w2, [x1]ffffffc0005421f8: 32000042 orr w2, w2, #0x1ffffffc0005421fc: 39000022 strb w2, [x1]ffffffc000542200: d65f03c0 ret ffffffc000542204 <test_bitfield2>:ffffffc000542204: f0000fa1 adrp x1, ffffffc000739000 <__hyp_idmap_text_end+0x4800>ffffffc000542208: f9426821 ldr x1, [x1,#1232]ffffffc00054220c: 52800000 mov w0, #0x0 // #0ffffffc000542210: 39400022 ldrb w2, [x1]ffffffc000542214: 321f0042 orr w2, w2, #0x2ffffffc000542218: 39000022 strb w2, [x1]ffffffc00054221c: d65f03c0 ret
可以看到,这种情况下最小访存单元是一个byte,在上面标黄的指令中会从内存读取一个副本,如果test_bitfield1在执行黄色指令后被test_bitfield2强行插入,test_bitfield2执行完毕后test_bitfield1继续执行,
在这种情况下test_bitfield2所做的修改会被丢弃。
所以平时如果需要用到bit filed struct, 需要注意:
1. 不同位域变量是不是在一个storage unit(可以通过反汇编查看)里面
2. 有没有被并发访问的可能。
下面这篇文章分析了这个问题并给出了几种解决方案:
https://www.securecoding.cert.org/confluence/display/seccode/CON32-C.+Prevent+data+races+when+accessing+bit-fields+from+multiple+threads
- One approach for preventing data races in concurrent programming is to use a mutex
- Another approach is to insert a non-bit-field member between any two bit-fields to ensure that each bit-field is the only one accessed within its storage unit.
- Use distinct non-bit-field members of a structure
位域结构体多线程访问出错的问题分析
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。