声明线程使用的 '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
before 和 after[=24= 】 来电。您可以按照 Linux 与 READ_ONCE
/WRITE_ONCE
相同的方式来组织它们,请参阅 here, and here。
以上内容甚至适用于临界区,您的程序无论如何都应该有临界区,因为多个线程同时修改共享状态。
我正在创建一个缓冲区以供某些线程访问。
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
before 和 after[=24= 】 来电。您可以按照 Linux 与 READ_ONCE
/WRITE_ONCE
相同的方式来组织它们,请参阅 here, and here。
以上内容甚至适用于临界区,您的程序无论如何都应该有临界区,因为多个线程同时修改共享状态。