自定义分配器使用移动线程向量

时间:2010-09-27 14:37:09

标签: c++ multithreading c++11 move-semantics move-constructor

我目前正在学习C ++中的并发性,并且遇到了使用线程向量的问题,我相信在C ++ 0x中这是可能的。但是,我当前的编译器似乎没有移动感知容器的实现,因此我生成了错误,因为删除了std::thread::thread(const std::thread&),即我只能使用std::thread移动构造函数/移动赋值

我认为我可以通过使用

编写自定义分配器来解决此问题
void MyAllocator::construct (pointer p, reference val)
/* should be non-const reference to val because using move constructor? */
{
    new ((void*)p) T (std::move(val));
}

而不是

void allocator::construct (pointer p, const_reference val)
{
    new ((void*)p) T (val);
}

?或者关于这个主题的一些其他变体(可能使用MyAllocator :: construct的重载)。

注意:这主要是为了进行短期的教育活动,并且能够充分利用容器中的线程来解决问题。我只是在这种情况下使用MyAllocator。但是,请指出我可能已经实施的任何图书馆,以便我可以在源头找到它。

3 个答案:

答案 0 :(得分:2)

解决问题的最简单方法是在堆上分配线程并操纵指针。

检查Boost Pointer Container库:boost::ptr_vector<std::thread>在我看来你在寻找什么。

答案 1 :(得分:2)

如果您的编译器没有提供移动感知std::vector,那么您必须编写自己的std::vector<std::thread>专门化而不是仅提供自定义分配器。整个C ++ 03 vector接口依赖于复制:push_back()复制元素; resize()使用作为第二个参数传递的元素的副本初始化空元素(即使这是T()的默认值);如果向量需要重新分配,则resize()reserve()insert()erase()push_back()复制元素,否则需要移动元素周围,​​等等。

这是一个常见的问题,我在std::thread的{​​商业性} just::thread实施中加入了这种专业化。

答案 2 :(得分:0)

std容器只接受可复制对象的要求更多地与C ++ 03容器接口有关,而不是与分配器实现有关。 例如

vector<T> b(100);
vector<T> a;
a=b;
assert(a==b);

标准向我们保证== b是真的。但是,如果T不可复制,那么在最好的情况下a = b将不会编译,在最坏的情况下a = b是未定义的。此外,

a.push_back(T());

可能会导致a分配新空间,并且在旧版本下会有新副本存储的副本。

此外,C ++ 03标准中没有任何内容表明实现实际上必须调用allocator.construct,事实上很多(例如gcc)都没有。

C ++ 0x标准为可移动类型的容器接口添加了新的成员函数,并阐明了operator =在其存在时的行为方式。

见www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2486.pdf