我正在创建一个缓冲区以供某些线程访问。
struct buffer {
struct items[32];
int numItems = 0; /*will keep track of number of items in the buffer
}; and will be updated by threads when accessed.
We'll include mutex locking*/
我应该将buffer
定为挥发性还是让numItems
易变?
我在想什么:我的理解是应该使用volatile来防止编译器优化线程对数据的原子访问之间的操作。如果我误解了这个
,请纠正我谢谢!
答案 0 :(得分:2)
如果要阻止编译器重新排序,合并或重新读取读取或写入,请使用易失性访问(uint8_t
类型为例):
*(volatile uint8_t *) p = *(uint8_t *) res;
如果您的类型是聚合的并且单个访问不可行,请在之前使用带有内存屏障的memcpy
,并在之后使用。您可以使用与READ_ONCE
/ WRITE_ONCE
相同的方式组织这些内容,请参阅here和here。
以上内容适用于您的程序应该具有的关键部分,因为多个线程同时修改共享状态。
答案 1 :(得分:-3)
限定符volatile不用于多线程。
如果变量被互斥锁正确保护,则不需要使用volatile或atomic限定符来定义它。
由互斥锁保护或由原子限定符定义的变量由编译器识别,不会以改变程序输出的方式进行优化。
只要您正确使用原子原语,就不必担心会删除对共享变量的写入或读取的编译器优化。编译器仍然可以执行优化,但它可能不会更改程序的intent(读取:输出)。