我有生产者和消费者线程,每个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;
}
};
请建议一个无锁方法来实现我上面尝试的方法。我想通过一些无锁方法在线程之间共享数据。
答案 0 :(得分:3)
该实现看起来正确,这意味着它没有数据竞争,并且它提供了所需的数据保护。但正如Casey已经评论过的那样,你有效地试图模仿互斥行为。而且您的实施效率较低,因此没有必要这样做。毕竟,尽管名称为AcqRel
,但该类实际上使用了默认的memory_seq_cst
语义。最好在这里真正使用获取/发布(虽然std::mutex
更好)。