2015-05-18 72 views
4

我在C++中使用构造“线程”,并在递归函数中创建可变数量的线程。我想让主线等待所有这些线程。我怎样才能做到这一点没有WaitForMultipleObjects?等待C++中的所有线程

+4

将它们存储在[容器](http://en.cppreference.com/w/cpp/container)中并等待它们循环?使用['std :: thread'](http://en.cppreference.com/w/cpp/thread/thread)真的没有其他办法。如果你想成为便携式和符合标准。 –

+0

我试图把它们放在一个向量中,但是当我执行push_back方法时,Visual Studio说线程不可复制 – Seba92

+0

@ user3671840你可以使用智能指针而不是线程 - 例如'std :: vector >' –

回答

15

在cplusplus中查看example。他们用向量中的push_back()存储线程。最后你有循环加入。

std::vector<std::thread> threads; 
//create threads 
for (int i=1; i<=10; ++i) 
    threads.push_back(std::thread(increase_global,1000)); 
//wait for them to complete 
for (auto& th : threads) 
    th.join(); 
+2

为什么这是downvote的原因? –

+2

不是我的投票,但它通常不如cppreference.com准确。 – MSalters

+0

同意cppreference.com是更准确的,但没有矢量的例子 :-( –

2

我不知道你的情况的细节,但这种方法可能对你有用:

using thread_vec = std::vector<std::thread>; 

void batch_process(int n) 
{ 
    static std::mutex mtx; 
    std::lock_guard<std::mutex> lock(mtx); 
    std::cout << "process: " << n << '\n'; 
} 

void recursive(thread_vec& tv, int n) 
{ 
    // do some stuff 
    tv.emplace_back(batch_process, n); 

    if(n > 0) 
     recursive(tv, n - 1); 
} 

int main(int, char* argv[]) 
{ 
    thread_vec tv; 

    recursive(tv, 3); 

    for(auto&& t: tv) 
     t.join(); 
} 

输出:

process: 1 
process: 0 
process: 2 
process: 3 
1

,将原子变量作为计数器,在启动新线程时增加变量,在线程完成后减少计数器。

int main() { 
    mutex m; 
    condition_variable cv; 
    atomic<int> counter = 0; 

    // .... in your recursive call 
    // increase counter when launching thread. 
    counter++; 
    thread t([](){ 
     // do whatever 
     lock_guard<mutex> lk(m); 
     counter--; 
     cv.notify_all(); 
    }); 
    t.detach(); // no need to join anymore. 
    // .... end recursive call 

    unique_lock<mutex> lock(m); 
    cv.wait(lock, [](){ return counter == 0; }); 
} 
+0

并将轮询开销(通过一些'condition_variable.wait()'实现)添加到解决方案中? – mg30rg

+4

@ mg30rg条件变量阻塞不轮询,线程连接也阻塞。 –

1

您也可以使用boost thread_group。它仅适用于boost线程,但它们与std :: thread的接口几乎相同(boost线程是C++ 11中标准库中线程的基础),并且一旦将所有线程添加到thread_group,只需在该组中调用join_all即可。你也可以实现你自己的thread_group类,与std :: thread一起工作,std :: thread会基本上完成已经建议的事情,并且使用线程对象或指针的向量,然后在循环中等待它们。