Qt基础开发之Qt多线程类QThread与Qt定时器类QTimer的详细方法与实例

2020-03-16 12:01:40王旭

需要特别注意的是:

    线槽函数已经执行完进入线程exec()中,可以通过发射信号重新让槽函数在线程中执行。也可以通过quit()退出线程exec()。 QObject派生类对象,将要调用moveToThread,不能指定一个主线程父对象托管内存。 QWidget的对象及派生类对象都只能在GUI主线程运行,不能使用moveToThread移到子线程中,即使没有指定父对象。

多线程对象内存释放

既然QObject对象无法托管内存对象,那么到底是先释放线程对象,还是先释放这个QObject对象?

先把QObject在线程循环中释放(使用QObject::deleteLater函数),然后QThread::quit,然后QThread::wait。

例如:

​mywork.h

#ifndef MYWORK_H
#define MYWORK_H
​
#include <QThread>
#include <QDebug>
class MyWork : public QObject
{
 Q_OBJECT
public:
​
 ~MyWork() { qDebug() << __FUNCTION__ << endl; }
public slots:
 void workSlot()
 {
  while(1)
  {
   qDebug() << "Work begin" << endl;
   QThread::sleep(5);
   qDebug() << "work end" << endl;
  }
 }
 void otherWorkSlot()
 {
  qDebug() << "otherWork begin" << endl;
  QThread::sleep(5);
  qDebug() << "otherWork end" << endl;
 }
​
​
};
​
#endif // MYWORK_H

widget.h

#ifndef WIDGET_H
#define WIDGET_H
​
#include <QWidget>
#include "mywork.h"
​
class Widget : public QWidget
{
 Q_OBJECT
​
public:
 Widget(QWidget *parent = 0);
 ~Widget();
private:
 QThread *_thread;
 MyWork * _myWork;
};
​
#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include <QPushButton>
#include "mywork.h"
#include <QThread>
#include <QHBoxLayout>
​
Widget::Widget(QWidget *parent)
 : QWidget(parent)
{
 _myWork = new MyWork;
 _thread = new QThread(this);
 _myWork->moveToThread(_thread);
 _thread->start();
​
 QPushButton *pb0 = new QPushButton("work", this);
 QPushButton *pb1 = new QPushButton("pb", this);
 QHBoxLayout *hBox = new QHBoxLayout(this);
 hBox->addWidget(pb0);
 hBox->addWidget(pb1);
 this->setLayout(hBox);
​
 /*发射信号给在另外一个线程的对象的队列中*/
 connect(pb0, SIGNAL(clicked()), _myWork, SLOT(workSlot()));
 connect(pb1, SIGNAL(clicked()), _myWork, SLOT(otherWorkSlot()));
​
 /*推荐用法释放内存*/
 //connect(_thread, SIGNAL(finished()), _myWork, SLOT(deleteLater()));
​
}
​
Widget::~Widget()
{
 _myWork->deleteLater(); //一定要在QThread线程退出之前
 _thread->quit();
 _thread->wait();
}

3、Qt线程的同步

​多线程在访问同时一个资源,(例如:多个线程可操作的变量、函数等),到底谁来使用这个资源是一个问题,就像一大群人去抢同一块蛋糕,可能其中一个人抢到,更有可能蛋糕被抢个稀烂。在多线程中,这个叫作竞争冒险。那么我们需要定一个规则来约束每一个人,比如:每个人排队来领蛋糕,这个在多线程中叫作同步方法。