Qt学习 —— QThreadPool和QRunnable之间的关系

导语

QRunnable 是所有 runnable 对象的基类,而 QThreadPool 类用于管理 QThreads 集合。

QRunnable 类是一个接口,用于表示一个任务或要执行的代码,需要重新实现 run() 函数。

QThreadPool 管理和循环使用单独的 QThread 对象,以帮助程序减少创建线程的成本。每个 Qt 应用程序都有一个全局 QThreadPool 对象,可以通过调用 globalInstance() 访问。


作为Qt类中少有的基类, QRunnable提供了简洁有效的可运行对象的创建. 用QRunnable来创建独立的运行对象来运行 不涉及界面元素的数据处理过程 非常合适.

优点: 创建过程简洁, 使用方便, 配合着自身的autoDelete特性, 有点“招之即来, 挥之即去”的感觉.
缺点: 无法实时提供自身的运行状态.

QThreadPool

QThreadPool 支持多次执行相同的 QRunnable,通过调用 QThreadPool::tryStart(this) 从 run() 函数内。如果启用了 autoDelete,当最后一个线程退出 run() 函数,QRunnable 将被删除。多次调用 QThreadPool::start() 使用相同的 QRunnable,当启用 autoDelete 时会创建一个竞争条件,不推荐使用。

一定时间未使用线程将会到期,默认到期超时是 30000 毫秒(30秒)。可以使用 setExpiryTimeout() 来改变,设定一个负值,则会禁用到期机制。

调用 maxThreadCount() 查询使用线程的最大数量。如果需要,可以使用 setMaxThreadCount() 进行更改。默认的 maxThreadCount() 是 QThread::idealThreadCount()。activeThreadCount() 函数返回当前正在工作线程的数量。

reserveThread() 函数储备一个线程用于外部使用。当线程完成后,使用 releaseThread(),以便它可以被重新使用。从本质上讲,这些函数暂时增加或减少活跃线程的数量,并且当实现耗时的操作时对 QThreadPool 是不可见的,这比较有用。

注意: QThreadPool 是一个管理线程的低级类,高级替代品可以用 Qt Concurrent 模块。

基本使用

要使用 QThreadPool 的一个线程,子类化 QRunnable 并实现 run() 虚函数。然后创建一个对象,并把它传递给 QThreadPool::start()。

	
class HelloWorldTask : public QRunnable
{
    void run() {
        qDebug() << "Hello world from thread " << QThread::currentThread();
    }
}
 
HelloWorldTask *hello = new HelloWorldTask();
 
// QThreadPool取得所有权,并自动删除 hello
QThreadPool::globalInstance()->start(hello);

默认情况下,QThreadPool 会自动删除 QRunnable。可以使用 QRunnable::setAutoDelete() 来改变自动删除标志。
和QThread的区别

QRunnable与QThread的区别

1.与外界通信方式不同。由于QThread是继承于QObject的,但QRunnable不是,所以在QThread线程中,可以直接将线程中执行的结果通过信号的方式发到主程序,而QRunnable线程不能用信号槽,只能通过别的方式,等下会介绍。
2.启动线程方式不同。QThread线程可以直接调用start()函数启动,而QRunnable线程需要借助QThreadPool进行启动。
3.资源管理不同。QThread线程对象需要手动去管理删除和释放,而QRunnable则会在QThreadPool调用完成后自动释放。

发布了187 篇原创文章 · 获赞 208 · 访问量 22万+

猜你喜欢

转载自blog.csdn.net/tonglin12138/article/details/103817929