使用std :: atomic同步的线程之间的共享数据

时间:2015-03-12 15:55:26

标签: multithreading c++11 atomic

我有生产者和消费者线程,每个1个。两者都必须共享一些数据(可以是一些用户定义的类的对象)。我想使用c ++ 11 std :: atomic来同步访问,这样如果消费者在生成器写入共享数据时进行读取,则消费者会等待生产者完成。

如果以下代码可以实现此目的,请查看代码并给出您的意见。您可以假设生产者和消费者线程正在调用set并获取使用某个数据对象初始化的SharedData类的对象。

感谢您的时间和宝贵的意见。

template <typename T>
class SharedData
{
    static const int SD_BUSY = 0x01;
    static const int SD_FREE = 0x02;
    typedef std::atomic<int> AtomicInt;

    struct AcqRel
    {
        AtomicInt& _atomInt;
        AcqRel(AtomicInt& atomInt) :_atomInt(atomInt)
        {
            int expectedValue = SharedData::SD_FREE;
            do
            {
                expectedValue = SharedData::SD_FREE;
            } while (!_atomInt.compare_exchange_strong(expectedValue, SharedData::SD_BUSY));
        }

        ~AcqRel()
        {
            _atomInt.store(SharedData::SD_FREE);
        }
    };

    AtomicInt _atomInt = SD_FREE;
    T _data;

public:
    void set(T& data)
    {
        AcqRel al(_atomInt);
        _data = data;
    }

    void get(T& data)
    {
        AcqRel al(_atomInt);
        data = _data;
    }
};

请建议一个无锁方法来实现我上面尝试的方法。我想通过一些无锁方法在线程之间共享数据。

1 个答案:

答案 0 :(得分:3)

该实现看起来正确,这意味着它没有数据竞争,并且它提供了所需的数据保护。但正如Casey已经评论过的那样,你有效地试图模仿互斥行为。而且您的实施效率较低,因此没有必要这样做。毕竟,尽管名称为AcqRel,但该类实际上使用了默认的memory_seq_cst语义。最好在这里真正使用获取/发布(虽然std::mutex更好)。