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) 默认构造了一个名为funstd::thread 对象。

最后一个block的错误是因为同样的原因

std::thread(func); //error C2371: 'func' : redefinition; different basic types

您正在尝试默认构造一个名为 funcstd::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 2013 发布编译不打开文件

Visual Studio 2013 OMP 发布模式

Visual Studio 2012/2013 类内成员初始化

以 Visual Studio 2013 结尾的错误环境变量路径

为啥我的 Visual Studio 2013 项目需要 mfc100.dll?

如何从visual studio 2013中禁用mscorlib.dll?