父线程join():阻塞直到孩子完成?

Posted

技术标签:

【中文标题】父线程join():阻塞直到孩子完成?【英文标题】:Parent thread join(): Blocks Until Children Finish? 【发布时间】:2014-12-11 20:35:46 【问题描述】:

我有一个执行多线程的 C++ 类。考虑下面的伪代码:

void MyClass::Open() 
  loop_flag =  true;
  // create consumer_thread (infinite loop)
  // create producer_thread (infinite loop)

void MyClass::Close() 
  loop_flag = false;
  // join producer_thread
  // join consumer_thread

MyClass::~MyClass() 
  Close();
  // do other stuff here

注意,consumer_thread、producer_thread及其相关函数都封装在MyClass中。调用者不知道他们的调用是多线程的,也不知道后台发生了什么。

现在,该课程是一个更大计划的一部分。该程序有一些初始的多线程来处理系统的配置,因为有很多事情会同时发生。

像这样(伪代码):

int main() 
  // create config_thread1 (unrelated to MyClass)
  // create thread for MyClass::Open()
  // ...
  // join all spawned configuration threads

所以我的问题是,当我为链接到 MyClass::Open() 的线程(即在 main() 中产生的配置线程)调用 join() 时,会发生什么?它是立即 join()(因为 MyClass::Open() 函数在创建 producer_thread 和 consumer_thread 后才返回)还是等待 producer_thread 和 consumer_thread 完成(因此挂起我的程序)。

提前感谢您的帮助。在实现细节方面,我在 Linux 机器上使用 Boost 线程。

编辑添加此图表:

 main()
 |
 |
 |
 |--->configuration_thread (that runs MyClass::Open())
   |
   |
   |----> producer_thread
   |----> consumer_thread

如果我在 configuration_thread() 上调用 join(),它是等到 producer_thread() 和 consumer_thread() 完成还是立即返回(并且 producer_thread() 和 consumer_thread() 继续运行)?

【问题讨论】:

'join' 等待线程完成。因此,您需要一个指示线程和所有子线程停止。 我明白这一点,但 MyClass::Open() 的线程何时结束?当函数返回或两个衍生线程完成时?我的目标是让 producer_thread 和 consumer_thread 运行,即使在 MyClass::Open() 线程加入后(如果有意义的话)。 Open() 将在创建线程后立即返回。线程将继续运行。 好吧,我明白了。但是当我在运行 Open() 的线程上调用 join() 时,producer_thread 和 consumer_thread() 是否继续运行? 是的,它们会继续运行,直到它们的函数返回或程序结束。 【参考方案1】:

一个(非分离的)线程将是可连接的,即使在从它被设置为运行的函数返回之后,直到它被连接。 示例:

#include <iostream>
#include <thread>
#include <chrono>

using namespace std;

void foo()
    std::cout << "helper: I'm done\n";


 int main()

    cout << "starting helper...\n";
    thread helper(foo);

    this::thread::sleep_for(std::chrono::seconds(5));

     cout << "helper still joignable?..." << (helper.joignable()?"yes!":"no...:(") << "\n";

    helper.join();
    cout << "helper joined!";

    cout << "helper still joignable?..." << (helper.joignable()?"really?":"not anymore!") << "\n";

    cout << "done!\n";


输出:

starting helper...
helper: I'm done
still joinable?...yes!
helper joined!
still joinable?...not anymore!
done!

至于join方法需要多少时间,我认为没有规定,但肯定不必等待所有其他线程完成,否则意味着只有一个线程将能够加入所有其他线程。

从 §30.3.5:

void 加入();

要求: joinable()true

效果:阻塞,直到 *this 表示的线程完成。

同步:*this所代表的线程的完成与对应的成功join()返回同步。 [注意:*this 上的操作未同步。 * -- 尾注*]

[...]

【讨论】:

以上是关于父线程join():阻塞直到孩子完成?的主要内容,如果未能解决你的问题,请参考以下文章

p_thread

boost - thread.join() 停止用户界面

13.4 控制线程

13.4 控制线程

07_控制线程_join_线程插队

多线程杂记