c++ - 我这里可以不使用线程同步吗?

标签 c++ multithreading c++11 mutex

我正在研究互斥体。

我想出了这个示例,它似乎无需任何同步即可工作。

#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++ - 我这里可以不使用线程同步吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41523832/

相关文章:

c++ - 使用 MS Visual Studio 2010 编译 C++ 程序不依赖于任何外部代码或可再发行组件

c++ - C/C++ 中的嵌套位域

multithreading - 如何使多个线程在单个TStringList上工作

c++ - For vs While 用于查找链表中的最后一项

c++ - Netbeans "__cplusplus"定义错误

c++ - 错误与否?带有 std::string 的 Visual Studio 2013 预览 std::vector 初始值设定项列表

C++ 在类中设置数组值

perl - 如何在 Perl 中的调用之间存储每个线程的状态?

c# - 在 C# 中读写的 volatile 与互锁

c++ - 带有 boost 文件系统 directory_iterator 的 Microsoft PPL parallel_for_each