【问题标题】:QThreadPool for large number of computation to be run simultaneously用于同时运行大量计算的 QThreadPool
【发布时间】:2014-05-06 08:00:27
【问题描述】:

我目前正在使用 QThreadPool 来运行一些计算,但是我发现如果我将所有内容都扔到 QThreadPool 中,它实际上表现不佳,并且似乎导致了一些崩溃问题。所以我的想法是一次只有几个线程传递到 QThreadPool 中。我想知道是否有人可以分享一些关于如何使用 QThreadPool 在一台 PC 上处理数千个计算的代码或示例。我写了如下的东西,但我觉得它现在给我造成了一些崩溃问题(A类继承自QRunnable):

for(int i=0;i<1000;i++)
{
    Class* A = new Class();
    A->doSomeSetting(i);

    A->setAutoDelete(true);

    connect(A,SIGNAL(OutputProvider(int))
       ,this,SLOT(OutputListener(int)),Qt::DirectConnection);

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

    m_thread_count++;

    if(m_thread_count >0 && m_thread_count %m_maxThreadInPool == 0)
    {
        QThreadPool::globalInstance()->waitForDone();
    }
}
QThreadPool::globalInstance()->waitForDone();

以及初始化设置:

m_maxThreadInPool = 4;
QThreadPool::globalInstance()->setMaxThreadCount(4);
m_thread_count = 0;
std::vector<int> output;

输出监听器:

void OutputListener(int output)
{
    output.push_back(output);
}

这是正确的做法还是有更好的方法?

同样在设置最大线程数时,您可以输入的最大数量是您可以拥有的核心数吗?

我也在使用 Qt::DirectConnection(我在使用 QueueConnection 时遇到了一些问题)。写入输出侦听器时会出现问题吗?

【问题讨论】:

  • 在使用线程时不能使用 Qt::DirectConnection。如果您在使用 Qt::QueuedConnection 时遇到问题,请先解决该问题。
  • 在添加更多线程之前无需等待线程完成。如果添加到 QThreadPoolQRunnable 对象的数量大于 maxThreadCount,它们将保留在队列中,直到有线程可用。
  • A-&gt;doSomeSetting() 内部发生了什么?如果这是您进行所有计算的地方,那么这就是您的问题所在,您的主要处理应该在 A-&gt;run() 内。
  • 我对 QueuedConnection 的问题是我有多层线程,而且似乎我缺少一个 QEventLoop。 (stackoverflow.com/questions/19374218/…) 你知道如何使用 QEventLoop 帮助信号/插槽连接进行吗?

标签: c++ multithreading qt threadpool computation


【解决方案1】:

Qt::DirectConnection 可能是个问题。如文档中所述,Queded 连接需要与线程一起使用。看看 QtConcurrent 和 QFuture 和 QFutureWatcher,这个类可能对你有所帮助

【讨论】:

    【解决方案2】:
    m_thread_count++;
    
    if(m_thread_count >0 && m_thread_count %m_maxThreadInPool == 0)
    {
        QThreadPool::globalInstance()->waitForDone();
    }
    

    您正在等待每 4 个任务完成所有:删除所有对 waitForDone 的调用,然后您将看到改进,QueuedConnection 将再次工作

    您可以添加比线程更多的任务,额外的任务将等待其他任务之一完成

    【讨论】:

    • 那么创建数千个A类并一次插入线程池就可以了吗?因为每次计算都会花费一些时间。
    • @JohnYang 是的,完全没问题,它会占用一些内存,但可以管理
    • 我在删除 waitForDone() 时遇到问题。该程序在创建 4 个线程并完成其中 2 个线程后崩溃。我也改成QueueConnection,也没用。
    猜你喜欢
    • 2015-03-13
    • 2014-12-03
    • 1970-01-01
    • 1970-01-01
    • 2017-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多