说我有一个类似
的仿函数struct F
{
// <some member variables go here>
void operator()() { while(true) /*do stuff affecting the state*/; }
};
如果我创建了一个Fs矢量
std::vector<F> functorVec(10);
然后用这些仿函数启动一堆线程
for (int i = 0; i < functorVec.size(); ++i)
{
boost::thread(functorVec[i]);
}
现在我为我的矢量做了一些事情,比如
functorVec.push_back(F());
如果向量扩展并将其内容复制到新位置,是否会导致线程中出现未定义的行为?或者他们会崩溃吗?
似乎他们的状态已经发生了变化,可能是在他们正在进行某些操作的过程中。实际上,复制然后删除了完成工作的对象,对吗?由于移动与线程的执行是异步的,因此它似乎是坏消息。我问,因为我希望能够保持每个运行自己的线程的对象集合。这些对象表示连接到系统的模块。我希望能够动态添加和分离模块。如果在集合中存储对象不是一个好主意,那么替代方案是什么?我是否必须在堆上分配它们并在我的集合中存储指针?
如果这根本不是问题,你能解释一下原因吗?
答案 0 :(得分:3)
boost :: thread的构造函数按值接受仿函数:
template <class F> explicit thread(F f);
这意味着它会复制您提供的仿函数,因此id不会引用您在仿函数向量中的对象。因此,应该没有影响。
答案 1 :(得分:3)
启动主题
通过传递可调用类型的对象来启动新线程 可以在没有参数的情况下调用构造函数。对象是 然后复制到内部存储中,并在新创建的上调用 执行的线程。如果不能(或不能)复制对象, 然后boost :: ref可用于传递对函数的引用 宾语。在这种情况下,Boost.Thread的用户必须确保 引用的对象比新创建的执行线程更长。
由于复制了线程参数,因此在启动所有线程后移动向量不会有问题。
答案 2 :(得分:3)
根据boost::thread documentation,您根本不需要存储仿函数。在构造时将复制可调用对象,并且永远不会再次引用您提供的原始文件。