【问题标题】:shared_ptr with QThreadPoolshared_ptr 与 QThreadPool
【发布时间】:2014-03-31 04:49:22
【问题描述】:

我目前正在将共享指针与 QThreadPool 一起用于多线程应用程序。但是,当线程完成计算时,我遇到了崩溃。

假设 A 类继承自 QRunnable,当将共享指针作为参数传入时,它会更新其类变量。代码如下:

for(int i=0;i<1000;i++)
{
    boost::shared_ptr<VariableType> variable = boost::make_shared<VariableType>();
    variable->Update_One_InternalVariable(1); // just updating a class variable inside VariableType

    Class* A = new Class(variable);
    A->setAutoDelete(true);

    QThreadPool::globalInstance()->start(A);

    m_thread_count++;

    if(m_thread_count >0 && m_thread_count %4== 0)
    {
        QThreadPool::globalInstance()->waitForDone(); // crashes after all threads finished here
    }
}
QThreadPool::globalInstance()->waitForDone();

在 4 个线程执行并结束后不久发生崩溃。我假设当 QThreadPool 尝试删除这些线程时会发生崩溃?有人可以指出我在多线程环境中使用共享指针是否做错了什么?

【问题讨论】:

  • 没有足够的信息来知道你做错了什么。其次,无论如何,您都不应该使用该全局 m_thread_count 来计算线程 - QThreadPool 会为您处理这个问题。最后,如果您想知道 shared_ptr 是否会导致问题,只需传入普通指针并查看它是否崩溃(对于您的示例,无论如何使用 unique_ptr 可能会更好).. 祝你好运。
  • 为什么要调用 waitForDone 所有四个迭代?它阻塞并销毁线程。线程重用是使用线程池的要点。只需将它们全部传递给 start(),线程池会将可运行对象排入队列。
  • 去掉QThreadPool::globalInstance()->waitForDone();在循环中,它甚至更早崩溃。不过,在这种情况下,我有时设法绕过了许多交互。它不是调用 waitForDone 所有四个交互。它正在阻止排队等候的太多事情。许多人建议不要使用它,但它似乎为我解决了一些问题。这就是为什么我怀疑问题出在我的 A 类中。shared_ptr 线程是否安全?

标签: c++ multithreading qt threadpool shared-ptr


【解决方案1】:

shared_ptr 不是线程安全的,因为不允许从多个线程访问 同一个实例。但是,使用两个指向同一个对象的shared_ptr 的不同实例是线程安全的,只要该对象本身是线程安全的。另见the documentation

因此,如果您将 shared_ptr 作为引用存储在 Class 中,则可能会崩溃。改为复制shared_ptr

【讨论】:

  • 事实上,这也适用于 Qt 中的所有隐式共享类:所有模板化容器、QStringQImage
猜你喜欢
  • 2011-09-27
  • 2013-06-18
  • 2010-12-18
  • 2012-03-03
  • 2012-01-07
  • 1970-01-01
  • 2014-03-25
  • 1970-01-01
  • 2013-07-26
相关资源
最近更新 更多