加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 在被另一个线程写入并在该线程加入之后从主线程访问变量是

发布时间:2020-12-16 03:25:45 所属栏目:百科 来源:网络整理
导读:这是线程安全的吗? 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()的顺序将引入一场比赛.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读