std :: atomic_thread_fence可能被误解了

时间:2016-07-01 10:08:59

标签: c++ c++11 atomic lock-free memory-barriers

我正在对C ++原子进行一种练习。

我编写了以下代码,其中我启动了2个读取器线程,这些读取器线程基于就绪计数器读取一些结构化数据,每次更新数据时主计数器都会增加2。每个读取器线程一旦标志为非零读取数据并将计数器递减1。 代码

#include <atomic>
#include <thread>
#include <iostream>
#include <functional>
#include <chrono>

struct Foo
{
    int a;
    int b;
    int c;
};

int main()
{
    unsigned long writeCnt { 0 };
    std::atomic<int> dataReady {0};

    //Shared data
    Foo data {0, 0, 0};

    //Readers accumulate data here
    Foo dataBuf[2][1000];

    //Reader threads  
    std::thread threads[2];

    //A pointer to a buffer assigned to a reader
    Foo (*curBuf)[1000] = dataBuf;

    //Thread's ID
    int threadNum  { 0 };

    //Starting readers
    for (auto & item : threads)
    {
        item = std::thread(std::bind([&dataReady,&data](Foo * buf, const int threadNum)
        {
            unsigned long readCnt { 0 };
            while (readCnt < 1000)
            {
                auto ready = dataReady.load(std::memory_order_relaxed);
                std::cout << "Thread #" << threadNum << " ready " << ready << " read cnt " << readCnt <<std::endl;
                if(ready > 0)
                {
                    std::atomic_thread_fence(std::memory_order_acquire);
                    buf[readCnt].a = data.a;
                    buf[readCnt].b = data.b;
                    buf[readCnt].c = data.c;
                    std::atomic_thread_fence(std::memory_order_release);
                    dataReady.store(ready - 1, std::memory_order_relaxed);
                    ++readCnt;
                }
                else
                {
                    continue;
                }
            }
        },*(curBuf++),threadNum++));
    }

    //Writer loop
    while (writeCnt < 1000)
    {
        auto ready = dataReady.load(std::memory_order_relaxed);
        std::cout << "Main thread ready " << ready <<  " write cnt " << writeCnt << std::endl;
        if(ready == 0)
        {
            std::atomic_thread_fence(std::memory_order_acquire);
            data.a = writeCnt;
            data.b = writeCnt;
            data.c = writeCnt;
            std::atomic_thread_fence(std::memory_order_release);
            dataReady.store(2, std::memory_order_relaxed);
            ++writeCnt;
        }
        else
        {
            continue;
        }
    }

    //Joining readers
    for(auto & item : threads)
    {
        if(item.joinable())
        {
            item.join();
        }
    }

    //Print accumulated data
    for(const auto & buffer : dataBuf)
    {
        for(const auto & item : buffer)
        {
            std::cout << item.a << " " << item.b << " " << item.c << std::endl;
        }
    }


}

现在,只有一个线程可以双读更新的数据并不重要。当读者完成阅读时,我担心writeCnt会在730左右停止。 这是由内存重新排序引起的不当行为以及为什么添加了线程围栏? 我在这里缺少什么?

0 个答案:

没有答案