矢量std :: threads

时间:2013-03-16 03:26:30

标签: c++ multithreading vector c++11 stdthread

C ++ 11

我正在尝试vector std::thread。以下三点的组合说我可以。

1。)根据http://en.cppreference.com/w/cpp/thread/thread/thread,     thread的默认构造函数创建

  

不代表线程的线程对象。

2.。根据http://en.cppreference.com/w/cpp/thread/thread/operator%3Dthread的{​​{1}}

  

指定[参数的状态,其中           是使用move的[调用线程]的线程右值引用]           语义。

3。)根据     http://en.cppreference.com/w/cpp/container/vector/vector,路过         只有向量构造函数的大小类型变量才会构造

  

具有[指定数量]值初始化的容器(默认构造,for   类)T的实例没有副本。

所以,我这样做了:

operator=

这在VC11和g++ 4.8.0 (online compiler here)中按预期运行,如下所示:

控制台输出:

#include <iostream>
#include <thread>
#include <vector>

void foo()
{
    std::cout << "Hello\n";
    return;
}

int main()
{
    std::vector<std::thread> vecThread(1);
    vecThread.at(0) = std::thread(foo);
    vecThread.at(0).join();
    return 0;
}

然后我在clang 3.2中尝试了它,通过切换同一网页上的编译器菜单,这给出了:

Hello

当代表线程的线程对象在被stderr: pure virtual method called terminate called without an active exception 编辑或join()编辑之前超出范围时,程序将被强制终止。我有detach() ed join(),所以唯一剩下的就是临时线程

vecThread.at(0)

中的

std::thread(foo);

分配。

但是,根据Web引用,只能通过移动线程右值引用来分配线程。我无法想到vecThread.at(0) = std::thread(foo);join()临时线程对象的任何方式。

因此,如果clang的输出是正确的,那么detach()的{​​{1}}有什么用?或者这是一个铿锵编译器错误?

在g ++ 4.8.0中,更改行

thread

operator=

(用括号替换括号)仍然会给出预期的vecThread.at(0) = std::thread(foo)输出。

然而,将行更改为vecThread.at(0) = std::thread{foo}会让人抱怨:

g ++ 4.8.0对大括号的投诉:

  

错误:从初始化列表转换为'std :: thread'会使用   显式构造函数'std :: thread :: thread(_Callable&amp;&amp;,_Args&amp;&amp; ...)   [with _Callable = void(&amp;)(); _Args = {}]'        vecThread.at(0)= {foo};

太先进了 - 我不知道它意味着什么。

在clang中进行相同的更改会带来更高级的效果:

clang 3.2对括号的投诉:

Hello

我也不知道这意味着什么。

我无法使用VC11来证实上述内容

vecThread.at(0) = {foo}

问题因为VC11,从2012年11月的CTP编译器开始,不支持标准库上的统一初始化语法。

1 个答案:

答案 0 :(得分:7)

你的第一个例子是正确的。当你使用clang和libstdc ++时,抛出异常是一个已知的bug。要解决它,您必须安装libc ++(llvm版本的c ++库)。请参阅下面的使用libc ++编译的示例

#include <thread>

int main()
{
    std::thread t([] () {});
    t.join();
    return 0;
}

$ clang++ -std=c++11 -stdlib=libc++ main.cpp -o main -lc++ -lsupc++ -lpthread

P.S。请参阅here,为什么还需要标记-lsupc++