我可以在这里不使用线程同步吗?
Can I use no thread synchronization here?
我正在研究互斥体。
我想出了这个似乎在没有任何同步的情况下工作的例子。
#include <cstdint>
#include <thread>
#include <iostream>
constexpr size_t COUNT = 10000000;
int g_x = 0;
void p1(){
for(size_t i = 0; i < COUNT; ++i){
++g_x;
}
}
void p2(){
int a = 0;
for(size_t i = 0; i < COUNT; ++i){
if (a > g_x){
std::cout << "Problem detected" << 'n';
}
a = g_x;
}
}
int main(){
std::thread t1{ p1 };
std::thread t2{ p2 };
t1.join();
t2.join();
std::cout << g_x << 'n';
}
我的假设如下:
线程 1 更改 g_x
的值,但它是唯一更改值的线程,因此理论上这假设是可以的。
线程 2 读取 g_x
的值。读取假定在 x86 和 ARM 上是原子的。所以那里也一定没有问题。我有几个读取线程的示例,它也可以正常工作。
换句话说,写入不是共享的,读取是原子的。
假设是否正确?
这里肯定存在数据竞赛:g_x
不是std::atomic
;它由一个线程写入,并由另一个线程读取。所以结果是不确定的。
请注意,CPU 内存模型只是交易的一部分。如果您没有正确声明共享变量,编译器可能会执行各种优化(使用寄存器、重新排序等)。
至于互斥体,这里不需要。将g_x
声明为原子应该删除 UB 并保证线程之间的正确通信。顺便说一句,即使您使用原子学,p2 中的 for 也可能被优化出来,但我认为这只是一个简化的代码,而不是真实的东西。
相关文章:
- 在C++中同步线程
- 将 10 个线程与原子布尔值同步
- 线程过程中的线程同步问题
- 如何定期同步线程?
- 同步线程安全的API,用于暴露缓存数据
- 如何在 pthreads 中正确同步线程
- 通过shared_ptr同步:线程清理器误报
- 如何同步线程以捕获相同数量的帧
- 同步线程和信号
- 使用条件变量(监视器)同步线程
- 同步线程创建和销毁(静态)对象
- NVIDA的CUDA"__syncthreads()"在传统C++中的等价物是什么。如何专业地同步线程?
- 使用事件同步线程
- 如何同步线程(消费者/生产者)
- 以最优雅的方式同步线程
- 使用互斥锁同步线程
- 计算着色器-如何全局同步线程
- GPU for loops:避免扭曲发散和隐式同步线程
- 如果已知访问顺序是安全的,如何在没有互斥锁的情况下同步线程/CPU
- Qt - 同步线程不起作用 - 线程停止但实际上不会停止,有时在不应该停止的时候停止