繁体   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