从C++中的另一个线程读取指针
Reading pointers from another thread in C++
在下面的代码中,线程 2 中x
的值将始终为 10,因为原子线程围栏。
int x;
atomic<bool> b(false);
// thread 1:
x = 10;
atomic_thread_fence(memory_order_release);
b = true;
// thread 2:
while(!b){}
atomic_thread_fence(memory_order_acquire);
assert(x == 10); // x will always be 10
但是在下面的代码中,线程 10 中的*x
2 将始终为 2 吗?
int* x = new int;
atomic<bool> b(false);
// thread 1:
*x = 10;
atomic_thread_fence(memory_order_release);
b = true;
// thread 2:
while(!b){}
atomic_thread_fence(memory_order_acquire);
assert(*x == 10); // will *x always be 10?
在这两种情况下,您都会得到10
,无论商店是直接完成还是通过指针完成,这里都没有区别。
这里不需要内存围栏,因为b = true
本质上是b.store(true, std::memory_order_seq_cst)
的 - 带有围栏的获取发布。
此类内存顺序可防止编译器围绕操作对存储和加载进行重新排序,并使前面的存储在此存储变得可见时对其他线程可见。
如果比较这两个函数的生成代码:
#include <atomic>
int x;
std::atomic<bool> b(false);
void f() {
x = 10;
std::atomic_thread_fence(std::memory_order_release);
b = true;
}
void g() {
x = 10;
b = true;
}
它是相同的:
f():
movl $10, x(%rip)
movb $1, b(%rip)
mfence
ret
g():
movl $10, x(%rip)
movb $1, b(%rip)
mfence
ret
不过,在您的特定情况下,在我看来,您只需要std::memory_order_release
商店即可b
使商店x
对其他线程也可见,围栏是不必要的。 即b.store(true, std::memory_order_release)
在这里就足够了。消费者代码需要做b.load(std::memory_order_acquire)
。
标准互斥锁确实在锁定时获取内存顺序,在解锁时释放内存顺序(这是术语获取/释放的来源),不涉及围栏。
很少需要显式围栏,主要是在硬件驱动程序中。在用户空间模式下,由于对 C++11 内存模型的误解,通常会放置代码围栏。围栏是最昂贵的原子同步机制,这是避免它们的主要原因。
相关文章:
- 全局变量 多读取器 一个写入器多线程安全?
- 静态 constexpr 类成员变量对多线程读取是否安全?
- C++线程安全:如果只有一个线程可以写入非原子变量,但多个线程从中读取. 会遇到问题吗?
- 跨线程共享读取资源
- 多个 OpenMP 线程读取(而不是写入)共享变量的性能成本?
- 我可以在没有任何锁的情况下从不同的线程读取内存缓冲区吗?
- 从C++中的另一个线程读取指针
- c++多线程读取文件
- 用c++对文件进行多线程读取
- 我需要保护一个由一个线程编写并由多个线程读取的变量吗
- 可能同时从不同的线程读取全局变量是否危险
- 防止其他线程读取资源
- 如何确保变量在不同的线程读取它们之前存储到内存中
- C++ pthread,两个线程读取一个全局变量
- 从多个线程读取数据的正确性
- 从多个线程读取访问
- 我什么时候需要一个无锁的数据结构来跨音频应用程序中的线程读取/写入数据
- 从控制台线程读取或获取命令
- 是否有必要锁定一个仅从一个线程写入且仅从另一个线程读取的数组?
- 当我从线程B读取相同的变量时,我能从线程a写入一个变量吗