微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

thread.join() 在多线程中做什么?

如何解决thread.join() 在多线程中做什么?

我想了解 C/C++ 中的线程连接。然后我才知道

std::thread::join() 函数使当前线程等待,直到由 *this 标识的线程执行完毕。

但我不明白为什么 join 函数的定位很重要,为什么这两个代码的工作方式不同。

代码 1:

#include <iostream>
#include <thread>
#include<vector>
#include <unistd.h>

using namespace std;

void func(int x)
{
  sleep(100);
  cout<<x<<endl;
}

int main() {
  
  vector<thread> a;

  for(int i=0;i<10;i++)
  {
    a.emplace_back(func,i);
  }

  for (auto &thr : a) {
      thr.join();
      cout<<"next"<<endl;
  }

  cout<<"finish"<<endl;
}

输出

01
3

next
9
7
45
6
8
2next


next
next
next
next
next
next
next
next
finish

代码 2:

#include <iostream>
#include <thread>
#include<vector>
#include <unistd.h>

using namespace std;

void func(int x)
{
  sleep(100);
  cout<<x<<endl;
}

int main() {
  
  vector<thread> a;

  for(int i=0;i<10;i++)
  {
    a.emplace_back(func,i);
    a.back().join();
    cout<<"next"<<endl;
  }

  cout<<"finish"<<endl;
}

输出

0
next
1
next
2
next
3
next
4
next
5
next
6
next
7
next
8
next
9
next
finish

起初我认为在代码 1 中,当我稍后加入线程时,它们可能已经执行并完成了,但是增加了睡眠时间给出了相同的结果。所以,我很困惑。

解决方法

在你的第一个版本的代码中,这个块

  for(int i=0;i<10;i++)
  {
    a.emplace_back(func,i);
  }

做 2 件事,它创建一个 std::thread 实例并启动线程。现在允许这些线程运行,直到主线程调用join()它们,就像在下一段代码中一样,

  for (auto &thr : a) {
      thr.join();
      cout<<"next"<<endl;
  }

所以你,

  1. 创建所有线程
  2. 让他们都跑起来
  3. 一一呼叫join()

在您的版本 2 中,您再次创建线程,然后立即通过 join()(即刚刚创建的线程)在最后插入的线程上调用 back()

  for(int i=0;i<10;i++)
  {
    a.emplace_back(func,i);
    a.back().join();
    cout<<"next"<<endl;
  }

因此每个线程都被启动,运行到完成,然后被调用 join()。您基本上序列化线程,因此输出。所以给你,

  1. 创建单线程
  2. 允许它运行
  3. 调用 join()
  4. 对所有线程重复此操作。
,

在第一个片段中,您启动所有线程,然后等待所有线程。在第二个代码段中,您在启动线程后立即等待它完成,然后再转到下一个线程,因此一次只有一个线程在运行。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。