Visual Studio 2013 标准::线程
Posted
技术标签:
【中文标题】Visual Studio 2013 标准::线程【英文标题】:Visual Studio 2013 std::thread 【发布时间】:2015-03-02 07:09:29 【问题描述】:以下程序在使用 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;
当这个程序工作时,可能会因为线程之间存在竞争条件而崩溃。主线程可能在其他线程之前结束。
有人知道为什么第二个块和最后一个块不起作用吗?
【问题讨论】:
【参考方案1】://compile but synstax error exist
auto func = []()
std::cout << " thread running2\n";
;
std::thread(fun); //fun is not defined
这里没有语法错误,std::thread(fun)
默认构造了一个名为fun
的std::thread
对象。
最后一个block的错误是因为同样的原因
std::thread(func); //error C2371: 'func' : redefinition; different basic types
您正在尝试默认构造一个名为 func
的 std::thread
对象,这是一个错误,因为同名的 lambda 已存在于同一范围内。要将 lambda 传递给 thread
构造函数,请改用大括号
std::threadfunc;
现在,在您进行这些更改后,您的代码将编译但将在运行时失败,因为块 1、3 和 4 中的线程对象都将调用 std::terminate
(当然,您的程序在第一个线程对象调用std::terminate
,所以其他两个这样做是有争议的)。
发生这种情况的原因是您在所有 3 个块中都有 可连接 线程,并且如果此类线程对象的 destructor 运行,std::terminate
will be called。为避免这种情况,您必须致电thread::join
(您也可以致电thread::detach
,但不要这样做)。
例如
//works
std::thread([]()
std::cout << " thread running1\n";
).join();
Live demo
【讨论】:
c++ 中的语法在哪里发生了变化?我的理解是 std::thread(func);将创建一个未命名的对象,将 func 传递给构造函数。 Ps 我的程序现在可以工作了:-) @Johan 一直都是这样。见this answer;如果你愿意,你可以添加更多的括号对:)以上是关于Visual Studio 2013 标准::线程的主要内容,如果未能解决你的问题,请参考以下文章
Visual Studio 2012/2013 类内成员初始化
以 Visual Studio 2013 结尾的错误环境变量路径