Ral*_*zky 10 c++ multithreading mutex memory-barriers c++11
比方说,我有两个线程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()
Run Code Online (Sandbox Code Playgroud)
是否可以观察修改fA
,并fB
在不同的线程不同的顺序C
和D
?换句话说,可以是以下程序
#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();
}
Run Code Online (Sandbox Code Playgroud)
合法打印
Thread C: fA = 1, fB = 0
Thread D: fA = 0, fB = 1
Run Code Online (Sandbox Code Playgroud)
根据C++标准?
注意:可以std::atomic<bool>
使用顺序一致的内存顺序或获取/释放内存顺序使用变量来实现自旋锁.所以问题是一个std::mutex
行为就像一个顺序一致的自旋锁或一个获取/释放内存顺序自旋锁.
是的,这是允许的,因此:不,std::mutex
不一定是顺序一致的.
std::mutex
标准中没有定义为顺序一致,只有那样
30.4.1.2互斥体类型[thread.mutex.requirements.mutex]
11同步:对同一对象的先前解锁()操作应与(1.10)此操作[lock()]同步.
Synchronize-with似乎定义在同一个std::memory_order::release/acquire
(见这个问题).
据我所知,获取/释放自旋锁将满足std :: mutex的标准.
归档时间: |
|
查看次数: |
1019 次 |
最近记录: |