标准中是否有任何措辞可以保证放松存储到原子的位置不会超过锁定互斥锁?如果没有,是否有任何措辞明确表示编译器或CPU是否可以这样做?
例如,采取以下计划:
std::mutex mu;
int foo = 0; // Guarded by mu
std::atomic<bool> foo_has_been_set{false};
void SetFoo() {
mu.lock();
foo = 1;
foo_has_been_set.store(true, std::memory_order_relaxed);
mu.unlock();
}
void CheckFoo() {
if (foo_has_been_set.load(std::memory_order_relaxed)) {
mu.lock();
assert(foo == 1);
mu.unlock();
}
}
Run Code Online (Sandbox Code Playgroud)
CheckFoo如果另一个线程同时调用SetFoo,是否有可能在上述程序中崩溃,或者是否有一些保证不能将存储foo_has_been_set提升到mu.lock编译器和CPU 的调用之上?
这与一个较旧的问题有关,但我并不是100%明白,答案适用于此.特别是,该问题的答案中的反例可能适用于两个并发调用SetFoo,但我对编译器知道有一个调用SetFoo和一个调用的情况感兴趣CheckFoo.这是否保证安全?
我正在寻找标准中的具体引用.谢谢!
比方说,我有两个线程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 …Run Code Online (Sandbox Code Playgroud) 这是一个关于C++标准的问题.我只能访问标准草案,所以如果官方标准不同,我道歉.如果我误解了它是如何工作的,请随时纠正我.
假设我有两个线程,一个写入字符串,另一个复制该字符串的内容.我保护对它们的访问使用std::mutex myMutex;
我知道你应该通常使用RAII类来锁定,我只是明确地使用了锁定和解锁来使示例更加明确.
// Global variable
std::string message;
std::mutex myMutex;
// Thread one
myMutex.lock();
message = "Hello";
myMutex.unlock();
// Thread two
myMutex.lock();
std::string copy = message;
myMutex.unlock();
Run Code Online (Sandbox Code Playgroud)
我的理解是,为了使它在线程之间可靠地工作,线程1必须在设置字符串后执行Release操作,并且两个必须在读取字符串之前执行Acquire.
阅读C++ 11的标准草案我看不到任何说明这样std::mutex做的事情,虽然很明显它是预期的,或者互斥体对任何东西都没用.
有人能指点我看相关部分吗?标准中的措辞对于随意的读者来说往往不是很清楚:)