【问题标题】:boost::thread runtime error when generating threads生成线程时的 boost::thread 运行时错误
【发布时间】:2011-12-19 00:28:42
【问题描述】:

我有一个项目,我们希望提供使用线程来加速一切。 我们希望能够在单独的线程中调用这个函数:

Request& Filter::processRequest(Request& req)

因此我将函数打包在 lambda 表达式中以访问返回值。

我现在收到以下运行时错误:

  glibc detected ... double free or corruption (!prev): ...

当我取消注释将线程添加到组的行时,一切正常。

boost::thread_group thread;
for (std::set<boost::shared_ptr<Filter> >::iterator i = sources_.begin();
    i != sources_.end(); ++i) {
         Request ret
         thread.add_thread(new boost::thread(boost::lambda::var(ret) = 
            (*i)->processRequest(req)));
         req+=ret;
         ...
}
thread.join_all();

此运行时错误的原因可能是什么。或者有没有另一种方法可以把这个函数放在单独的线程中?

【问题讨论】:

  • 您希望boost::lambda::var(ret) = (*i)-&gt;processRequest(req) 做什么?您在添加 N 个线程的循环中......那么 N 个稳定的“ret”位置在哪里通过引用存储结果?
  • 我在上面的代码中添加了我想要对 ret 执行的操作。我想把它加到req中。我认为每个线程都放了一份 ret 副本,还是这个假设有误?
  • 我不是真正的boost::lambda 用户,我只是对boost::thread 做了一点修改,所以我实际上对你的方法了解不多(尽管它让我觉得“不可以工作的方式”)。如果你启动一个异步任务,你不能在没有某种保证它已经完成计算的情况下使用它的结果。并且文档建议boost::lambda::var 通过引用获取一个参数(如果它“复制”它,调用者将如何连接到副本?)......所以你真的只有一个 Request ret; 每次迭代都是“活的”循环。
  • 我担心我必须重新设计我的程序以使函数无效。谢谢回复。我希望可能有一些其他的建议,否则我会关闭这个问题。

标签: c++ boost-thread


【解决方案1】:

如果这种技术完全有效,您将需要多个可以稳定引用的 ret 值(每个执行线程一个)。而且您必须等到线程连接完成后才能使用这些值。

您可以尝试的一个简单修改就是在vector&lt;Request&gt; retValues...的循环之外创建一个向量,然后在每次add_thread 时向向量添加一个元素并传递对该元素的引用。那么如果你等到加入之后才使用这些值,也许它会起作用?

boost::thread_group thread;
vector<Request> retValues;
for (std::set<boost::shared_ptr<Filter> >::iterator i = sources_.begin();
    i != sources_.end(); ++i) {
         retValues.push_back(0);
         thread.add_thread(new boost::thread(
            boost::lambda::var(retValues.back()) = 
            (*i)->processRequest(req)));
         ...
}
thread.join_all();
// retValues safe to use here...

(注意:可能不需要使用boost::lambda;您可以使用 boost::bind 连接到存储结果的工作类:

Getting return value from a boost::threaded member function?

...但实际上,无论您需要什么,每个线程都需要一个单独的变量来存储结果...其生命周期的持续时间足以让线程能够对其进行写入。)

【讨论】:

  • 我不认为从boost::thread 派生是一个好主意,因为它没有虚拟析构函数。还是我弄错了?
  • 嗯,看来你是对的。诡异的。我猜它和QThread有很大的不同……让我再看一遍……doc.qt.nokia.com/latest/qthread.html#details
  • 感谢您的回复。我会试一试。我也会看看 QThreads。
  • 我大部分时间都在 Qt 宇宙中,所以我很享受它...进一步查看 boost::thread 我现在记得你无法从它们中获得。 :-/ 无论如何,如果您有兴趣弄乱 Qt 示例,最快的方法是使用 Qt Creator...将示例单键克隆到新环境并轻松构建:qt.nokia.com/products/developer-tools
猜你喜欢
  • 2010-10-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多