Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
320 views
in Technique[技术] by (71.8m points)

c++ - Can multiple threads write the same value to the same variable at the same time safely?

Can multiple threads write the same value to the same variable at the same time safely?

For a specific example — is the below code guaranteed by the C++ standard to compile, run without undefined behavior and print "true", on every conforming system?

#include <cstdio>
#include <thread>

int main()
{
    bool x = false;
    std::thread one{[&]{ x = true; }};
    std::thread two{[&]{ x = true; }};
    one.join();
    two.join();
    std::printf(x ? "true" : "false");
}

This is a theoretical question; I want to know whether it definitely always works rather than whether it works in practice (or whether writing code like this is a good idea :)). I'd appreciate if someone could point to the relevant part of the standard. In my experience it always works in practice, but not knowing whether or not it's guaranteed to work I always use std::atomic instead - I'd like to know whether that's strictly necessary for this specific case.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

No.

You need to synchronize access to those variables, either by using mutexes or by making them atomic.

There is no exemption for when the same value is being written. You don't know what steps are involved in writing that value (which is the underlying practical concern), and neither does the standard which is why code has undefined behaviour … which means your compiler can just make absolute mayhem with your program (and that's the real issue you need to avoid).

Someone's going to come along and tell you that such-and-such an architecture guarantees atomic writes to these sized variables. But that doesn't change the UB aspect.

The passages you're looking for are:

[intro.races/2]: Two expression evaluations conflict if one of them modifies a memory location ([intro.memory]) and the other one reads or modifies the same memory location.

[intro.races/21]: […] The execution of a program contains a data race if it contains two potentially concurrent conflicting actions, […]. Any such data race results in undefined behavior.

… and the surrounding wording. That section is actually quite esoteric, but you don't really need to parse it as this is a classic, textbook data race that you can read about in any book on programming.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...