std :: mutex用法示例

Emm*_*oli 0 c++ multithreading mutex data-race

我把这段代码写成了测试:

#include <iostream>
#include <thread>
#include <mutex>

int counter = 0;

auto inc(int a) {
    for (int k = 0; k < a; ++k)     
        ++counter;
}

int main() {

    auto a = std::thread{ inc, 100000 };
    auto b = std::thread{ inc, 100000 };

    a.join();
    b.join();

    std::cout << counter;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

counter变量是全球性的,因此,创建2个线程ab,我希望找到一个数据的比赛.输出为200000而不是随机数.为什么?

此代码是一个固定版本,它使用一个mutex全局变量只能访问一次(每次1个线程).结果仍然是200000.

std::mutex mutex;

auto inc(int a) {
    mutex.lock();
    for (int k = 0; k < a; ++k)     
        ++counter;
    mutex.unlock(); 
}
Run Code Online (Sandbox Code Playgroud)

事实是这样的.互斥解决方案给了我200000这是正确的,因为只有1威胁在时间可以访问计数器.但为什么非互斥解决方案仍然显示200000?

Mat*_*lia 6

这里的问题是你的数据竞争非常小.任何现代编译器都会将你的inc函数转换为counter += a,所以竞争窗口非常小 - 我甚至会说,一旦你启动第二个线程,第一个线程已经完成了.

这并没有使这个不明确的行为,但解释了你看到的结果.您可能会使编译器对您的循环不那么聪明,例如通过制作akcounter volatile; 那么你的数据竞争应该变得明显.