我需要一段代码来设置几个并发运行的线程,在它们全部完成之后,打印一些东西来通知用户。这是代码(在Windows上使用c ++ 11的库):
void func1(){
int j = 0;
while(j<=100000) j++;
}
int main(){
for(int i = 0; i < 5; i++){
std::thread t(func1);
printf("releasing thread %d\n",i);
t.join();
printf("all threads finished\n");
}
}
我认为这将使所有线程同时运行,但结果是它一次只运行一个线程,等到它完成,然后执行下一个线程。 外出:
releasing thread 0
releasing thread 1
releasing thread 2
releasing thread 3
releasing thread 4
all threads finished
在这种情况下,如果不将线程分开,那么join()的重点是什么?我该怎么做才能实现我所描述的目标?
答案 0 :(得分:6)
请看这个例子。你必须启动所有线程,然后再加入它们。
答案 1 :(得分:0)
要回答第二个问题,如果没有join()
调用,线程将同时运行,但没有内置的数据争用保护,这是您需要处理的问题。
答案 2 :(得分:0)
显示的代码不会生成显示的输出。您错放了{
。
#include <thread>
#include <vector>
#include <iostream>
void func1(int i){
int j = 0;
while(j<=100000) j++;
std::cout << "thread " << i << " finished\n";
}
int main(){
std::vector<std::thread> threads;
try {
for(int i = 0; i < 5; i++){
threads.push_back(std::thread(func1, i));
}
} catch (...) {
}
for( std::thread& t : threads ) {
t.join();
}
std::cout << "all threads finished\n";
}
join
做的是让你的主线程等到有问题的thread
完成。
通常,您应该避免在原始版本中使用std::thread
,因为join
或detach
失败将导致您的程序终止。因此,上面有一个非常激进的try
/ catch
块:它远远不够。
std::async
更容易使用:
void func1(int i){
int j = 0;
while(j<=100000) j++;
std::cout << "thread " << i << " finished\n";
}
int main(){
std::vector<std::future> threads;
try {
for(int i = 0; i < 5; i++){
threads.push_back(std::async(func1, i));
}
}
for( std::future& f : threads ) {
f.wait();
}
std::cout << "all threads finished\n";
}
总的来说。但请注意,MSVC 2012和2013 std::async
不符合标准,上述代码也不安全。
一般情况下,您应该将自己的线程原语包装在自己的RAII包装器中,以用于除了微不足道的任何事情之外的任何内容。