簡體   English   中英

在被另一個線程寫入並在該線程加入之后從主線程訪問變量是否安全?

[英]Is it safe to access a variable from the main thread after it was written to by another thread and after that thread was joined?

這是線程安全的嗎?

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()的順序將引入一場比賽。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM