通过比较锁定并交换布尔值
locking with compare and swap on a boolean
我正在试验 atomic_compare_and_swap
函数来对 std::atomic<bool>
进行基本锁定。
我期望的行为是第二个线程,即 Consume
将一直阻塞在 Access::get()
开始的 while
循环中,直到原子 [=16] =] 设置为 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;
}
生产者线程执行set()
和CAS循环时,会看到UNLOCKED_
和lock_
的值相同(false
),设置lock_
为真,returns 为真。因此,循环退出,该线程等待 20 秒。
同时,你施加的 3 秒延迟
this_thread::sleep_for(std::chrono::seconds(3));
in main() 仍在滴答,当它过期时,消费者线程执行 get()
并且 CAS 循环将首先看到 UNLOCKED_
是 false
但 lock_
为真(因为它是由生产者设置的),因此它将 UNLOCKED_
的值更新为 true
并再次旋转。在 CAS 循环的下一次迭代中,它会看到 lock_
和 UNLOCKED_
现在都是 true
(UNLOCKED_
是在上一次迭代中设置的),然后循环中断出去。
我正在试验 atomic_compare_and_swap
函数来对 std::atomic<bool>
进行基本锁定。
我期望的行为是第二个线程,即 Consume
将一直阻塞在 Access::get()
开始的 while
循环中,直到原子 [=16] =] 设置为 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;
}
生产者线程执行set()
和CAS循环时,会看到UNLOCKED_
和lock_
的值相同(false
),设置lock_
为真,returns 为真。因此,循环退出,该线程等待 20 秒。
同时,你施加的 3 秒延迟
this_thread::sleep_for(std::chrono::seconds(3));
in main() 仍在滴答,当它过期时,消费者线程执行 get()
并且 CAS 循环将首先看到 UNLOCKED_
是 false
但 lock_
为真(因为它是由生产者设置的),因此它将 UNLOCKED_
的值更新为 true
并再次旋转。在 CAS 循环的下一次迭代中,它会看到 lock_
和 UNLOCKED_
现在都是 true
(UNLOCKED_
是在上一次迭代中设置的),然后循环中断出去。