简体   繁体   English

我如何等待线程在Qt中完成而不阻止其执行?

[英]How do I wait for a thread to finish in Qt without blocking its execution?

I have a function that creates a bunch of QThreads to speed up a long calculation, but when I try and sleep until the calculation is done, the background threads never execute for some reason. 我有一个函数,可以创建一堆QThreads来加快计算速度,但是当我尝试睡眠直到计算完成时,由于某些原因,后台线程将永远不会执行。

I can't figure out why the threads don't execute after I call thread->start() . 我无法弄清楚为什么在调用thread->start()之后不执行thread->start() Here's my code: 这是我的代码:

multithread.run_multithread(run_function, thread_count);
while(multithread.running)
    QThread::msleep(100);
qDebug() << "done";  // Never reaches this point

And the multithread function: 和多线程功能:

void Multithread::run_multithread(std::function<void
 (int)>run_function_in, int thread_count) {
    running = true;
    // Create workers and threads
    int thread_idx;
    for(thread_idx=0; thread_idx<thread_count; thread_idx++) {
        ThreadWorker *worker = new ThreadWorker(this, run_function_in);
        QThread *thread = new QThread();
        // Set workers and threads to delete when done
        worker->moveToThread(thread);
        connect(worker, &ThreadWorker::finished, this, &Multithread::check_progress);
        connect(thread, &QThread::started, worker, &ThreadWorker::run);
        connect(worker, &ThreadWorker::finished, thread, &QThread::quit);
        connect(worker, &ThreadWorker::finished, worker, &ThreadWorker::deleteLater);
        connect(thread, &QThread::finished, thread, &QThread::deleteLater);
        // Start thread
        thread->start();
    }
}

running gets set to false in Multithread::check_progress when all the threads finish their part of the calculation. 当所有线程都完成其计算的一部分时,在Multithread::check_progressrunning会被设置为false When I remove QThread::msleep(100) the calculation will execute normally, but I need some way to block until it completes. 当我删除QThread::msleep(100) ,计算将正常执行,但是我需要某种方法来阻塞直到完成。

Rather than using QThread, I would recommend using the Qt Concurrent functionality which provides a higher level of abstraction over the thread primitives. 我建议不要使用Qt并发功能,而应使用Qt并发功能,该功能在线程基元上提供了更高级别的抽象。 You can use QFutureSynchronizer to wait for several concurrent futures to finish. 您可以使用QFutureSynchronizer等待几个并发的QFutureSynchronizer完成。 This object will wait for all attached futures to finish before it allows itself to be destroyed. 该对象将等待所有附加的期货完成,然后才能销毁自身。

An example of how to start several threads and then wait for them all to finish is: 如何启动多个线程然后等待所有线程完成的示例是:

#include <QtConcurrent>

void run_multithread(...) {
  // Set up a new synchronizer.
  QFutureSynchronizer<void> synchronizer;

  // Run n tasks in parallel.
  for (int thread_idx = 0; thread_idx < thread_count; ++thread_idx) {
    synchronizer.addFuture(QtConcurrent::run(run_function_in));
  }

  // The synchroniser will wait for all threads to finish before returning.
}

It could be because of optimization, since multithread.running is not changed inside the loop. 这可能是由于优化,因为multithread.running在循环内未更改。 However, here the main reproducible reason is that the slot Multithread::check_progress is never called by ThreadWorker::finished signals, since the instance of Multithread belongs to your current thread, but the event loop is blocked. 但是,这里的主要可复制原因是ThreadWorker::finished信号永远不会调用插槽Multithread::check_progress ThreadWorker::finished ,因为Multithread的实例属于您当前的线程,但是事件循环被阻止了。

Instead of such sleep you can emit a signal from Multithread object when all threads are finished. 当所有线程完成时,您可以从Multithread对象发出信号来代替这种睡眠。 Then the computation may be continued from a slot connected to that signal. 然后可以从连接到该信号的时隙继续计算。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM