【发布时间】:2015-09-10 17:11:25
【问题描述】:
假设我有一个QObject 和一个阻塞方法(比如说,它是一个库调用,需要在返回之前从网络中获取大量数据)。
class Foo : public QObject {
Bar* _bar;
public:
// non blocking call, emits stuffDone when done
void startStuff(int a, int b);
signals:
void stuffDone(int sum);
}
class Bar {
public:
// Blocking call
int doStuff(int a, b) {
for(int i=0; i<=100000000000; i++);
return a + b;
}
}
我希望我的 Foo::startStuff 方法在适当的(单独的)线程中运行 doStuff 并在完成时触发 stuffDone 信号。
startStuff 必须立即返回。
Bar可以在必要时成为 QObject,从而允许通过moveToThread设置线程亲和性
这样做的最简单和最惯用('Qt-like')的方式是什么?
【问题讨论】:
-
documentation to QThread 似乎为您的问题提供了两个简单的答案。你有什么理由不能使用这些吗?
-
@Rostislav 该文档并未提供完整的图片。手动实例化线程,而不是使用线程池,通常是一个坏主意。线程很昂贵。
-
要异步运行直到完成,您永远不需要使用显式线程 - 您应该使用线程池。
-
@KubaOber 线程池很棒——我自己在我的应用程序中使用它们。但是,我不同意总是使用它们。如果线程大部分时间都花在等待 I/O 上——最好不要将它放入线程池中——操作系统会更好地调度它。然而,线程池不会让其他任务在前一个任务结束之前运行(如果池有更多线程 - 那么等待 I/O 的 N 个任务将阻止下一个任务运行)。对于这样的任务,QFuture 确实会更好。对于计算密集型任务 - 线程池更好。
-
@Rostislav 我认为你不应该在启动之后创建线程..
标签: c++ qt asynchronous signals blocking