Visual Studio 2013 std::thread

Visual Studio 2013 std::thread

以下程序在使用 Visual Studio 2013 编译时会出现一些奇怪的 compile/run-time 行为:

#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;
}

当这个程序运行时,可能会因为线程之间存在竞争条件而崩溃。主线程可能会在其他线程之前结束。

有人知道为什么第二块和最后一块不起作用吗?

{//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::thread{func};

现在,在您进行这些更改后,您的代码将编译但在运行时会失败,因为块 1、3 和 4 中的线程对象都将调用 std::terminate(当然,您的程序当第一个线程对象调用 std::terminate 时终止,所以其他两个线程对象调用是有争议的)。

发生这种情况的原因是您在所有 3 个块中都有 joinable 个线程,如果 destructor of such a thread object runs, std::terminate will be called。为避免这种情况,您必须调用 thread::join(您也可以调用 thread::detach,但不要那样做)。

例如

{//works
    std::thread([](){
        std::cout << " thread running1\n";
    }).join();
}

Live demo