這是線程安全的嗎?在主線程被另一個線程寫入並且線程被加入後訪問變量是否安全?
int x = 0;
std::thread([&]{ x = 1; }).join();
std::cout << x;
變量x是在不使用原子或鎖的情況下從兩個線程訪問的。但是,撥打join()
強制對x的訪問是連續的。
此處是否需要內存屏障?
這是線程安全的嗎?在主線程被另一個線程寫入並且線程被加入後訪問變量是否安全?
int x = 0;
std::thread([&]{ x = 1; }).join();
std::cout << x;
變量x是在不使用原子或鎖的情況下從兩個線程訪問的。但是,撥打join()
強制對x的訪問是連續的。
此處是否需要內存屏障?
是的,那個特別的代碼片段是線程安全的;不需要屏障或鎖。
這是事件的時間表相對於你的代碼:
thread 1
--------
|
int x = 0;
(write 0 to x)
|
std::thread thread 2
(start thread 2) --------> --------
| |
join(); x = 1;
(thread 1 suspended) (write 1 to x)
. |
. thread 2 returns
. |
(thread 1 resumes) <------- x
|
std::cout << x;
(read from x)
|
thread 1 returns
|
x
正如你所看到的,在任何一點x
由多於一個線程訪問。實際上,正如你猜測的那樣,使用join()
有效地使所有對x
的訪問按順序發生。 join()
提供了同步來代替從鎖獲得的同步。
基本上,你擁有的是一個如何使用零併發多線程的例子。
當然,這僅僅是因爲調用join()
,這是在您提供的代碼片段中創建線程後立即發生的。如果不是有這樣的事情:
int x = 0;
std::thread t([&]{ x = 1; });
std::cout << x;
t.join(); // Move join() call here
的時間表,而不是看起來可能是這樣:
thread 1
--------
|
int x = 0;
(write 0 to x)
|
std::thread thread 2
(start thread 2) --------> --------
| |
std::cout << x; x = 1;
(read from x) (write 1 to x) <-- PROBLEM!
| |
join(); |
(thread 1 suspended) |
. |
. thread 2 returns
. |
(thread 1 resumes) <------- x
|
thread 1 returns
|
x
改變的join()
這樣的順序將引入的比賽。
沒有數據競爭=沒有需要 – user2485710