一、简介
QRunnable这是一个轻量级的抽象类,用于开始一个另外线程的任务。这种任务是运行过后就丢弃的。
由于这个类是抽象类,我们需要继承QRunnable,然后重写其纯虚函数QRunnable::run(),用法同Qthread类似。
二、使用方法
通过调用QThreadPool::start(runable)函数,我们将一个Qrunable对象放入QThreadPool的执行队列。
一旦有线程可用,线程池将会选择一个QRunnable对象,然后在那个线程开始执行。
2.1 实例化QRunnable方法
实例化QRunnable类,重写QRunnable的run函数,并传到QThreadPool的start函数中
class HelloWorldTask:public QRunnable
{
void run() override
{
qDebug() << "Hello world from thread" << QThread::currentThread();
}
};
//1.实例化QRunnable类,重写QRunnable的run函数,并传到QThreadPool的start函数中
HelloWorldTask *hello = new HelloWorldTask();
// QThreadPool 取得 hello 的所有权并自动删除它
QThreadPool::globalInstance()->start(hello);
2.2 使用QRunnable类的静态函数create()方法
使用QRunnable类的静态函数create函数,生成QRunnable对象,传到QThreadPool的start函数中
//(Qt5.15之后的方法)
[static] QRunnable *QRunnable::create(std::function<void ()>functionToRun)
//2.使用QRunnable类的静态函数create函数,生成QRunnable对象,传到QThreadPool的start函数中
QRunnable* pWork = QRunnable::create([](){
qDebug() << "start pWork from thread" << QThread::currentThread();
QThread::sleep(3);
qDebug() << "end pWork from thread" << QThread::currentThread();
});
QThreadPool::globalInstance()->start(pWork);
2.3 运行结果
Hello world from thread QThreadPoolThread(0x382f0f8, name = "Thread (pooled)")
start pWork from thread QThreadPoolThread(0x382eff8, name = "Thread (pooled)")
end pWork from thread QThreadPoolThread(0x382eff8, name = "Thread (pooled)")
从结果可以看出QRunnable::run()函数和QRunnable::create()函数都运行在线程池中。符合预期。
2.4 总结和QThread的区别
- 与外界通信方式不同。由于QThread是继承于QObject的,但QRunnable不是,所以在QThread线程中,可以直接将线程中执行的结果通过信号的方式发到主程序,而QRunnable线程不能用信号槽;
- 启动线程方式不同。QThread线程可以直接调用start()函数启动,而QRunnable线程需要借助QThreadPool进行启动;
- 资源管理不同。QThread线程对象需要手动去管理删除和释放,而QRunnable则会在QThreadPool调用完成后自动释放。
- 关于多线程QRunnable的用法,可以参考我的另一篇博客Qt多线程的三种方法之一QThread
关于多线程QConcurrent的用法,可以参考我的另一篇博客Qt多线程的三种方法之三QtConcurrent::run()+QThreadPool