【发布时间】:2017-01-25 09:12:37
【问题描述】:
说,我有两个线程 A 和 B 分别写入全局布尔变量 fA 和 fB,它们最初设置为 false 并受 std::mutex 对象 mA 和mB分别:
// Thread A
mA.lock();
assert( fA == false );
fA = true;
mA.unlock();
// Thread B
mB.lock()
assert( fB == false );
fB = true;
mB.unlock()
是否可以在不同的线程C和D中以不同的顺序观察fA和fB的修改?也就是说,可以下面的程序
#include <atomic>
#include <cassert>
#include <iostream>
#include <mutex>
#include <thread>
using namespace std;
mutex mA, mB, coutMutex;
bool fA = false, fB = false;
int main()
{
thread A{ []{
lock_guard<mutex> lock{mA};
fA = true;
} };
thread B{ [] {
lock_guard<mutex> lock{mB};
fB = true;
} };
thread C{ [] { // reads fA, then fB
mA.lock();
const auto _1 = fA;
mA.unlock();
mB.lock();
const auto _2 = fB;
mB.unlock();
lock_guard<mutex> lock{coutMutex};
cout << "Thread C: fA = " << _1 << ", fB = " << _2 << endl;
} };
thread D{ [] { // reads fB, then fA (i. e. vice versa)
mB.lock();
const auto _3 = fB;
mB.unlock();
mA.lock();
const auto _4 = fA;
mA.unlock();
lock_guard<mutex> lock{coutMutex};
cout << "Thread D: fA = " << _4 << ", fB = " << _3 << endl;
} };
A.join(); B.join(); C.join(); D.join();
}
合法打印
Thread C: fA = 1, fB = 0
Thread D: fA = 0, fB = 1
根据 C++ 标准?
注意:可以使用std::atomic<bool> 变量使用顺序一致的内存顺序或获取/释放内存顺序来实现自旋锁。所以问题是std::mutex 的行为是否类似于顺序一致的自旋锁或获取/释放内存顺序自旋锁。
【问题讨论】:
-
编辑了我的答案(不确定你是否收到通知),现在它几乎与以前相反,std::mutex is 就像一个获取/释放自旋锁,但也你给出的输出是不可能的
标签: c++ multithreading c++11 mutex memory-barriers