正确使用std :: atomic,预增量值作为函数参数

时间:2017-03-09 09:24:26

标签: c++ multithreading c++11 atomic

我有代码,我需要唯一的id(某些协议的数据包ID)。所以我使用了std::atomic<int>。在阅读documentation之后,我感到困惑,因为它表示增量是以这种方式完成的。 fetch_add(1)+1

我理解fetch_add内的值以原子方式递增,但我在原子操作之外得到预增值+1。我猜的不是原子。

我可以使用some_func(++atomic_value)吗?

我编写了简单的代码来检查它是否有效。它有效,但我不明白为什么。

#include<iostream>
#include <atomic>
#include <thread>
#include <vector>
#include <random>
#include <mutex>
#include <algorithm>

std::atomic<int> Index = 0;
//int Index = 0; // non atomic Index. It will generate duplicities

std::vector<int> Numbers;
std::mutex Mutex;
std::default_random_engine Generator;
std::uniform_int_distribution<int> Distribution(5, 10);

void func(int Value)
{
    std::lock_guard<std::mutex> Guard(Mutex);
    Numbers.push_back(Value);
}

void ThreadProc()
{
    Sleep(Distribution(Generator));
    func(++Index); // is this proper usage of std::atomic?
}

int main()
{
    const int ThreadCount = 1000;
    std::vector<std::thread> Threads;

    for ( int i = 0; i < ThreadCount; i++ )
    {
        Threads.push_back(std::thread(ThreadProc));
    }

    for_each(Threads.begin(), Threads.end(), [](std::thread& t) { t.join(); });

    std::sort(Numbers.begin(), Numbers.end());
    auto End = std::unique(Numbers.begin(), Numbers.end());

    if ( Numbers.end() == End )
    {
        std::cout << "No duplicites found." << std::endl;
    }
    else
    {
        std::cout << "Duplicites found ! - " << Numbers.end() - End << std::endl;
        for_each(End, Numbers.end(), [](int n) { std::cout << n << ", "; });
    }

    return 0;
}

偏离主题的问题:当我将Index定义为非原子时,我得到重复,但只是从范围的末尾开始。数字总是900+。为什么会这样?

0 个答案:

没有答案