以下程序在使用Visual Studio 2013编译时会产生一些奇怪的编译/运行时行为:
#include "stdafx.h"
#include <thread>
#include <chrono>
#include <iostream>
int main()
{
{//works
std::thread([](){
std::cout << " thread running1\n";
});
}
{//compile but synstax error exist
auto func = [](){
std::cout << " thread running2\n";
};
std::thread(fun); //fun is not defined
}
{//compile, see next block for mystery compile error
auto func = [](){
std::cout << " thread running2\n";
};
std::thread tmp(func);
}
{//does not compile and don't know why
auto func = [](){
std::cout << " thread running2\n";
};
std::thread(func); //error C2371: 'func' : redefinition; different basic types
}
return 0;
}
当该程序工作时,由于线程之间存在竞争条件,可能会崩溃。主线程可以在其他线程之前结束。
有人知道为什么第二个区块和最后一个区块不起作用吗?
答案 0 :(得分:3)
{//compile but synstax error exist
auto func = [](){
std::cout << " thread running2\n";
};
std::thread(fun); //fun is not defined
}
此处没有语法错误,std::thread(fun)
默认构造名为std::thread
的{{1}}对象。
最后一个块中的错误是由于相同的原因
fun
您正尝试默认构造上面名为std::thread(func); //error C2371: 'func' : redefinition; different basic types
的{{1}}对象,这是一个错误,因为同一范围内已经存在同名的lambda。要将lambda传递给std::thread
构造函数,请使用大括号
func
现在,在您进行了这些更改后,您的代码将被编译但在运行时将失败,因为第1,3和3区中的线程对象4都将调用thread
(当然,当第一个线程对象调用 std::thread{func};
时,程序终止,所以其他两个执行此操作是一个没有实际意义的点。)
发生这种情况的原因是,您在所有3个块中都有 joinable 线程,并且如果此类线程对象的destructor运行,则std::terminate
will be called。为避免这种情况,您必须致电std::terminate
(您也可以致电std::terminate
但不要这样做。)
例如
thread::join