什么线程竞争的影响?

时间:2017-07-24 12:36:08

标签: multithreading

如您所见,当我删除mt.lock()和mt.unlock时,结果小于50000。

为什么?实际发生了什么?如果你能为我解释,我将非常感激。

#include <iostream>
#include <thread>
#include <vector>
#include <mutex>
using namespace std;
class counter{
public:
    mutex mt;
    int value;
public:
    counter():value(0){}
    void increase()
    {
        //mt.lock();                                                                                                                                                                           
        value++;
        //mt.unlock();
    }
};

int main()
{
    counter c;
    vector<thread> threads;
    for(int i=0;i<5;++i){
        threads.push_back(thread([&]()
                                 {
                                    for(int i=0;i<10000;++i){
                                        c.increase();
                                    }
                                 }));
    }
    for(auto& t:threads){
        t.join();
    }
    cout << c.value <<endl;
    return 0;
}

1 个答案:

答案 0 :(得分:0)

++实际上是两个操作。一个是读取值,另一个是递增值。由于它不是原子操作,因此在同一代码区域中运行的多个线程会混淆。

例如,考虑在同一区域中运行的三个线程没有任何锁定:

  1. 主题1和2将value读为999
  2. 线程1将递增的值计算为1000并更新变量
  3. 线程3读取1000,递增到1001并更新变量
  4. 线程2将递增的值计算为999 + 1 = 1000并使用1000
  5. 覆盖3的工作

    现在,如果您使用的是"fetch-and-add"指令,其中 是原子的,那么您就不需要任何锁定。见fetch_add