shared_ptr 与 QThreadPool
Posted
技术标签:
【中文标题】shared_ptr 与 QThreadPool【英文标题】:shared_ptr with 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 线程是否安全? 【参考方案1】:shared_ptr
不是线程安全的,因为不允许从多个线程访问 同一个实例。但是,使用两个指向同一个对象的shared_ptr
的不同实例是线程安全的,只要该对象本身是线程安全的。另见the documentation
因此,如果您将 shared_ptr
作为引用存储在 Class
中,则可能会崩溃。改为复制shared_ptr
。
【讨论】:
事实上,这也适用于 Qt 中的所有隐式共享类:所有模板化容器、QString
、QImage
。以上是关于shared_ptr 与 QThreadPool的主要内容,如果未能解决你的问题,请参考以下文章
[C++11]shared_ptr共享智能指针的初始化与使用