int main() {
int f = 0, x=0;
std::thread *t = new std::thread([&f, &x](){ while(f == 0); std::cout << x << endl;});
std::thread *t2 = new std::thread([&f, &x](){ x = 42; f = 1;});
t->join();
t2->join();
return 0;
}
、theoritically stdoutが(私たちは、結果として42
を期待している私たちの直感に反対0
に等しい取得することが可能である。しかし、CPUは発注指示の外に実行することができ、実際に、それはにpossbileですそのために、プログラムを実行します。 マルチスレッドとOOO実行。私が知っていることから、
ので、thread#2
(なぜならOOOのmeachanismの)最初の実行される第2のコア上f = 1
、その後、thread#1
(私たちは私たちのCPUで> 1つのコアがあると)最初のコアで実行される最初のプログラム:while(f == 0); std::cout << x << endl
。したがって、出力はです。
私はそのような出力を得ようとしましたが、私はいつも42
を取得します。私はそのプログラムを1000000回実行し、結果は常に同じ= 42
でした。
(私はそれが安全ではないことを知っています、データ競争があります)。
私の質問は以下のとおりです。
- アム私は正しいか、私が間違っていますか?どうして?
- 私が正しいとすれば、出力を
0
にすることは強制できますか? - このコードを安全にするには?私はmutex/semaphoresについて知っていて、mutexで
f
を保護することができましたが、私はメモリフェンスについて何か聞いてきました。
UBはUBです。 std :: atomicを参照してください。 –
アトミックの使用は実際にはここで重要です。あなたのコードは私のシステム(gcc6.1 -O3)で終わることさえありません。また、なぜポインタビジネスですか?スレッドを自動変数として宣言するだけです。 –
@RichardCritten、アトミックな操作が順不同で実行できないことは確かですか? – Gilgamesz