qt有参数的多线程:Qt的线程池QThreadPool
qt有参数的多线程:Qt的线程池QThreadPool可以看到新建的任务在子线程中执行了。可喜可贺,不过好像哪里不对劲?有好几个线程是重复的。是的因为这个线程池的最大线程数是4。可以通过setMaxThreadCount来设置最大的线程数。Widget::Widget(QWidget *parent) : QWidget(parent) ui(new Ui::Widget) { ui->setupUi(this); m_pThreadPool = new QThreadPool; for(int i = 0; i < 10; i) { m_pThreadPool->start(new CTask()); //执行任务 } } 运行结果: 1.用QtCreator新建一个基于QWidget的工程。 2.新建一个类CTask,从QRunnable继承。并重写run函数。void CTask::run()
线程可以帮助我们处理耗时的操作以防止界面卡死,也可以提高程序的并发性。但线程也不是创建越多越好,因为创建、销毁线程以及切换线程都是需要消耗资源的。线程池技术的出现就是为了解决这个问题。线程池维护一定数量的线程,并充分使用它们。Qt封装的线程池类是QThreadPool 它的使用需要QRunnable来配合。概括一下使用步骤如下:
1.从QRunnable派生一个类,重写run()函数。把需要子线程干的活放到run函数中。
2.调用QThreadPool的start()开始工作,start的参数就是子类化QRunnable的指针。
使用步骤很简单,写个例子。
1.用QtCreator新建一个基于QWidget的工程。
2.新建一个类CTask,从QRunnable继承。并重写run函数。
void CTask::run() { qDebug()<<"fearlazy is doing something"<<QThread::currentThreadId(); }
3.在Widget中创建一个QThreadPool对象,并用它来启动10个任务。
Widget::Widget(QWidget *parent) : QWidget(parent) ui(new Ui::Widget) { ui->setupUi(this); m_pThreadPool = new QThreadPool; for(int i = 0; i < 10; i) { m_pThreadPool->start(new CTask()); //执行任务 } }
运行结果:
可以看到新建的任务在子线程中执行了。可喜可贺,不过好像哪里不对劲?有好几个线程是重复的。是的因为这个线程池的最大线程数是4。可以通过setMaxThreadCount来设置最大的线程数。
线程池在执行完任务后会自动删除任务对象(在start中new出来的CTask),除非你使用setAutoDelete(false)。 QRunnable除了run也就这点本事了。下图为证。
最后提一点就是Qt为每个QApplication创建了一个线程池对象,通过QThreadPool的静态成员函数globalInstance()可以获得这个对象。不用怀疑拿起来用就是了,出了问题我又不负责任。