声明线程使用的 'volatile' 数据类型

Declaring 'volatile' data type to be used by threads

我正在创建一个缓冲区以供某些线程访问。

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 来防止编译器对线程对数据的原子访问之间的操作进行优化。如果我对此有误解,请纠正我

谢谢!

限定符 volatile 不用于多线程。

如果一个变量被互斥体正确保护,那么它不需要用限定符 volatile 或 atomic 来定义。

受互斥锁保护或使用原子限定符定义的变量可被编译器识别,不会以改变程序输出的方式进行优化。

只要您正确使用原子基元,就不必担心会删除对共享变量的写入或读取的编译器优化。编译器仍然可以执行优化,但它可能不会改变程序的意图(读取:输出)。

如果要防止编译器重新排序、合并或重新获取读取或写入,请使用易失性访问(uint8_t 类型是一个示例):

*(volatile uint8_t *) p = *(uint8_t  *) res;

如果您的类型是聚合类型并且单个访问不可行,请使用带有内存屏障的 memcpy beforeafter[=24= 】 来电。您可以按照 Linux 与 READ_ONCE/WRITE_ONCE 相同的方式来组织它们,请参阅 here, and here

以上内容甚至适用于临界区,您的程序无论如何都应该有临界区,因为多个线程同时修改共享状态。