std :: thread - 如何使主线程继续运行,子线分支关闭

时间:2015-06-05 17:12:18

标签: c++ multithreading c++11

我正在开发一个项目,我想创建一个从主线程分支出来的线程,但在返回之前不会阻塞它。我的意思是我需要主线程来创建子线程,并且主线程继续工作,而子线程分开(分支关闭)。

为了简单起见,我重新创建了一个较小规模的代码版本:

#include <iostream>
#include <thread>

using namespace std;

void wait() {
    std::this_thread::sleep_for(std::chrono::duration<int, std::ratio<1,1000>>(200));
}

void one() {
    static int x = 0;
    while(true) {
        cout << "one" << endl;
        wait();
    }
}

void two() {
    while(true) {
        cout << "two" << endl;
        wait();
    }
}

int main() {
    thread t1(one);
    thread t2(two);

    t1.join();
    t2.join();

    cout << "Do stuff beyond here..";

    while(true) {
        cout << "three" << endl;
        wait();
    }

    return 0;
}

我的问题是三分球在两人完成之后才开始出现..有没有办法解决这个问题?我已经尝试省略对join的调用,但这只会导致程序崩溃。

非常感谢任何帮助。

3 个答案:

答案 0 :(得分:4)

最简单的解决方案

我想到的第一个想法就是推迟加入:

atomic<bool> finished=false; 

thread t1(one, &finished);  // signature could be changed to inform when finished
thread t2(two, &finished);

// do your processing here, 
while (! finished) 
    // ......

t1.join();
t2.join();

唯一的限制是树访问必须同步,即主线程应该知道其他线程中正在进行的事情,并且应该避免竞争条件。当其他线程完成时,也应该通知它,例如,使用共享原子。

<强>替代

您还可以detach其他主题:

t1.detach(); 
t2.detach(); 

答案 1 :(得分:2)

来自http://www.cplusplus.com/reference/thread/thread/join/

  

<强>的std ::螺纹::加入

     

该函数在线程执行完成时返回。

     

这会使此函数返回的时刻与线程中所有操作的完成同步:这将阻止调用此函数的线程的执行,直到构造返回的函数返回(如果它没有& #39; t)。

当你调用join时,主线程停止执行并等待子线程完成。

尝试将join移动到main()的底部。

还有RE:

  

我已尝试省略加入的调用,但这只会导致程序崩溃。

https://stackoverflow.com/a/13984169/3294441

解释了这种行为
  

调用线程析构函数而不先调用join(等待它完成)或者分离是为了保证立即调用std :: terminate并结束程序

答案 2 :(得分:1)

在线程超出范围之前,join是必需的。只需尽可能晚地连接螺纹即可。

在这种情况下循环之后,就在main函数返回之前。

如果你的函数会在某个未知点退出,你可以使用thread::detach,但这会带来它自己的捕获。