【发布时间】:2013-03-16 17:00:11
【问题描述】:
C++11
我正在尝试制作std::threads 中的vector。结合以下三点说我可以。
1.) 根据http://en.cppreference.com/w/cpp/thread/thread/thread,
thread 的默认构造函数创建一个
不代表线程的线程对象。
2.) 根据http://en.cppreference.com/w/cpp/thread/thread/operator%3D, thread 的operator=
分配[参数的状态,其中 是使用 move 对 [调用线程] 的线程右值引用] 语义。
3.) 根据 http://en.cppreference.com/w/cpp/container/vector/vector,通过 只有向量构造函数的大小类型变量会构造
具有[指定数量]值初始化的容器(默认构造,对于 classes) T 的实例。不复制。
所以,我这样做了:
#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;
}
这在 VC11 和 g++ 4.8.0 (online compiler here) 中按预期运行,如下所示:
控制台输出:
Hello
然后我在 clang 3.2 中进行了尝试,通过在同一网页上切换编译器菜单,得到:
stderr:
pure virtual method called
terminate called without an active exception
当代表线程的线程对象在join()ed 或detach()ed 之前超出范围时,程序将被强制终止。我有join()ed vecThread.at(0),所以唯一剩下的就是临时线程
std::thread(foo);
在
vecThread.at(0) = std::thread(foo);
任务。
然而,根据网络参考,线程只能通过移动线程右值引用来分配。我想不出任何办法来join() 或detach() 临时线程对象。
那么如果clang的输出是正确的,那么thread的operator=有什么用呢?或者这是一个clang编译器错误?
在 g++ 4.8.0 中,换行
vecThread.at(0) = std::thread(foo)
到
vecThread.at(0) = std::thread{foo}
(用大括号替换圆括号)仍然给出预期的Hello 输出。
但是,将行更改为 vecThread.at(0) = {foo} 会使其抱怨:
g++ 4.8.0 对大括号的抱怨:
错误:从初始化列表转换为 'std::thread' 将使用 显式构造函数 'std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (&)(); _Args = {}]' vecThread.at(0) = {foo};
太高级了——我不知道是什么意思。
在 clang 中进行相同的更改可以提供更高级的功能:
clang 3.2 对大括号的抱怨:
error: no viable overloaded '='
vecThread.at(0) = {foo};
...
note: candidate function not viable: cannot convert initializer list
argument to 'const std::thread'
thread& operator=(const thread&) = delete;
...
note: candidate function not viable: cannot convert initializer list
argument to 'std::thread'
thread& operator=(thread&& __t) noexcept
我也不知道这意味着什么。
我不能用VC11来证实上述情况
vecThread.at(0) = {foo}
问题是因为 VC11,截至 2012 年 11 月的 CTP 编译器,不支持标准库上的统一初始化语法。
【问题讨论】:
-
你是用
-pthread编译的吗?代码看起来不错,虽然有点冗长。 -
您的意思是我应该将
–pthread添加到在线编译器的compiler/interpreter参数文本字段中吗?我将它添加到网页的文本字段的原始编译器/解释器参数中,使其在 clang 上为-std=c++11 -Wall -W -pedantic -O2 –pthread,但在调用terminate时得到了相同的结果。 -
好吧,this code 在使用
-std=c++0x -pthread编译时对我有用... -
我为名为@987654357@ 的liveworkspace 写了一个小sn-p。玩它而不是 std::thread
-
AFAIK,当您使用标志
-stdlib=libstdc++编译时会引发此异常。这是众所周知的bug。有些人建议使用 llvm c++ 库,但我现在无法确认。你可以检查一下,如果你已经安装了这个库(在编译器参数中添加-stdlib=libc++)。
标签: c++ multithreading vector c++11 stdthread