【问题标题】:Starting thread from for loop blocks UI从 for 循环块 UI 启动线程
【发布时间】:2013-01-04 15:12:40
【问题描述】:

我正在压缩视频,将来我想一次压缩多个帧。我有一个线程,我调用它来处理每个帧 - 这就是为什么我的 UI 类中有 for 循环。问题是 UI 被阻止了。为什么?这是因为我从 for 循环中调用线程吗?

导致 UI 阻塞的代码 (Dialog.cpp):

for(int i=0; i<nFrames; i++)
{
    //grab next frame from video source

    myThread.setFrame(newFrame);
    myThread.start();
    myThread.wait();
    result.append(myThread.GetResult());
}

【问题讨论】:

  • 启动一个单独的线程并立即等待它有什么意义?
  • 我使用了 wait() ,因为没有它,for 循环将立即重新启动线程,不会产生任何结果。这不正确吗?
  • 问题是如果您立即阻止等待线程完成,那么线程根本没有任何意义。您的单线程 UI 阻塞并让步到第二个线程并继续让步,直到任务在第二个线程中完成。在这种情况下,您可以只完成主线程的工作。您不能在这样的循环中创建线程。您可能想使用信号和插槽、QtConcurrent 或线程池来完成此操作,但我没有时间解释这两种解决方案。
  • 不用解释了,我自己去读。感谢您提及!

标签: c++ multithreading qt user-interface block


【解决方案1】:

你打电话给wait,为什么你指望wait不会阻塞ui?

来自 Qt 文档:

阻塞线程直到满足以下任一条件:

与此 QThread 对象关联的线程已完成执行 (即当它从 run() 返回时)。此函数将返回 true 如果 线程已完成。如果线程没有,它也返回 true 已经开始了。 time 毫秒已经过去。如果时间是 ULONG_MAX (默认),那么等待永远不会超时(线程必须 从运行()返回)。如果等待计时,此函数将返回 false 出去。

【讨论】:

  • 但是如果我不使用 wait(),那么 for 循环会在执行任何操作之前重新启动线程吗?我应该为每个框架使用一个新线程吗?
  • @PrimožKralj 如果你想一次做多件事情,你需要多于 1 个线程。请注意,不受控制的线程数量是一个坏主意,并且比在单个线程中执行它会减慢您的速度。您可能需要诸如任务池、生产者-消费者队列之类的东西。
【解决方案2】:

From doc:

bool QThread::wait (unsigned long time = ULONG_MAX)

阻塞线程直到满足以下任一条件:

此 QThread 对象关联的线程已完成执行(即当它从 run() 返回时)。

...

这提供了与 POSIX pthread_join() 类似的功能 功能。

你不应该在这里使用wait

【讨论】:

    猜你喜欢
    • 2015-09-30
    • 1970-01-01
    • 2018-01-04
    • 2017-03-27
    • 2013-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-22
    相关资源
    最近更新 更多