I'm using the construct "thread" in C++ and I create a variable number of thread in a recursive function. I want the main thread to wait for all of them. How can I do it without WaitForMultipleObjects ?
我在C ++中使用构造“thread”,我在递归函数中创建了一个可变数量的线程。我希望主线程等待所有这些。没有WaitForMultipleObjects我怎么能这样做?
4 个解决方案
#1
16
Take a look at example in cplusplus. They store threads with push_back() in vector. At the end you have loop with joins.
看看cplusplus中的例子。它们在向量中存储带有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
2
Use an atomic variable as a counter, increase the variable when launching new thread, in the thread decrease the counter once the thread is completed.
使用原子变量作为计数器,在启动新线程时增加变量,在线程完成后减少计数器。
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; });
}
#3
2
I don't know the specifics of your situation but this kind of approach might be useful to you:
我不知道您的具体情况,但这种方法可能对您有用:
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();
}
Output:
process: 1
process: 0
process: 2
process: 3
#4
1
You could also use boost thread_group. It only works with boost threads, but they have a nearly identical interface to std::thread (boost threads were the basis for threads in the standard library in C++11), and once you add all your threads to the thread_group, you simply call join_all on the group. You could also implement a thread_group class of your own, to work with std::thread, which would essentially do what has already been suggested, with a vector of thread objects or pointers, and waits on them in a loop.
你也可以使用boost thread_group。它只适用于boost线程,但是它们与std :: thread的接口几乎相同(boost线程是C ++ 11中标准库中线程的基础),一旦你将所有线程添加到thread_group,只需在组上调用join_all即可。您还可以实现自己的thread_group类,使用std :: thread,它基本上可以执行已经建议的内容,使用线程对象或指针的向量,并在循环中等待它们。
#1
16
Take a look at example in cplusplus. They store threads with push_back() in vector. At the end you have loop with joins.
看看cplusplus中的例子。它们在向量中存储带有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
2
Use an atomic variable as a counter, increase the variable when launching new thread, in the thread decrease the counter once the thread is completed.
使用原子变量作为计数器,在启动新线程时增加变量,在线程完成后减少计数器。
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; });
}
#3
2
I don't know the specifics of your situation but this kind of approach might be useful to you:
我不知道您的具体情况,但这种方法可能对您有用:
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();
}
Output:
process: 1
process: 0
process: 2
process: 3
#4
1
You could also use boost thread_group. It only works with boost threads, but they have a nearly identical interface to std::thread (boost threads were the basis for threads in the standard library in C++11), and once you add all your threads to the thread_group, you simply call join_all on the group. You could also implement a thread_group class of your own, to work with std::thread, which would essentially do what has already been suggested, with a vector of thread objects or pointers, and waits on them in a loop.
你也可以使用boost thread_group。它只适用于boost线程,但是它们与std :: thread的接口几乎相同(boost线程是C ++ 11中标准库中线程的基础),一旦你将所有线程添加到thread_group,只需在组上调用join_all即可。您还可以实现自己的thread_group类,使用std :: thread,它基本上可以执行已经建议的内容,使用线程对象或指针的向量,并在循环中等待它们。