我正在尝试atomic_compare_and_swap
函数对std::atomic<bool>
进行基本锁定。
我期待的行为是第二个线程,即Consume
在while
循环中始终被Access::get()
保持阻塞状态lock_
设置为true
。
由于sleeps
我已经介绍了它始终是第一个线程Produce
将原子设置为true
以防止第二个线程继续进行。
不幸的是情况并非如此,我可以看到第二个线程立即执行,并且根本不会被阻止。
我做错了什么?
我正在使用g++4.9 on Lubuntu
class Access
{
atomic<bool> lock_;
bool UNLOCKED_;
public:
Access() : lock_(false), UNLOCKED_(false){}
void set()
{
// lock
while(!atomic_compare_exchange_strong(&lock_, &UNLOCKED_, true)) {}
this_thread::sleep_for(std::chrono::seconds(20));
cout << "set" << endl;
}
void get()
{
// lock
while(!atomic_compare_exchange_strong(&lock_, &UNLOCKED_, true)){}
cout << "get" << endl;
}
};
Access gTest; // global
void Produce() { gTest.set(); }
void Consume() { gTest.get(); }
int main() {
thread producer(Produce);
this_thread::sleep_for(std::chrono::seconds(3));
thread consumer(Consume);
producer.join();
consumer.join();
return 0;
}
答案 0 :(得分:2)
当生产者线程执行set()
和CAS循环时,它会看到UNLOCKED_
和lock_
的值相同(false
),设置{{ 1}}为true,返回true。因此,循环退出,此线程等待20秒。
与此同时,你用
施加了3秒的延迟lock_
在main()中的仍然在滴答作响,当它到期时,消费者线程执行this_thread::sleep_for(std::chrono::seconds(3));
并且CAS循环将首先看到get()
是UNLOCKED_
但是false
是true(因为它是由生产者设置的),因此它将lock_
的值更新为UNLOCKED_
并再次旋转。在CAS循环的下一次迭代中,它将看到true
和lock_
现在都是UNLOCKED_
(在前一次迭代中设置了true
),并且循环中断出。