我正在试验atomic_compare_and_swap函数,以便对std::atomic<bool>执行基本锁。
我所期望的行为是,第二个线程,即Consume,将在while循环中的Access::get()开始时一直被阻塞,直到原子lock_被设置为true。
由于我介绍的sleeps,它始终是第一个将原子设置为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;
}发布于 2015-03-29 21:50:01
当生产者线程执行set()和CAS循环时,它将看到UNLOCKED_和lock_的值是相同的(false),将lock_设置为true,并返回true。因此,循环退出,此线程等待20秒。
同时,你所施加的3秒延迟
this_thread::sleep_for(std::chrono::seconds(3));main()仍然在滴答作响,当它过期时,使用者线程执行get(),而UNLOCKED_循环将首先看到UNLOCKED_是false,但lock_是真的(因为它是由生产者设置的),因此它再次将UNLOCKED_的值更新为true和自旋。在CAS循环的下一次迭代中,它将看到lock_和UNLOCKED_现在都是true (在上一次迭代中设置了UNLOCKED_),并且循环出现了。
https://stackoverflow.com/questions/29333633
复制相似问题