Qt有两种多线程的方法,其中一种是继承QThread的run函数,另外一种是把一个继承于QObject的类转移到一个Thread里。
Qt4.8之前都是使用继承QThread的run这种方法,但是Qt4.8之后,Qt官方建议使用第二种方法。两种方法用起来都比较方便,但继承QObject的方法更加灵活。这里要记录的是如何正确的创建一个线程。
值得注意的是第一种方法只有run()里面在新的线程里,第二种方法就可以在新线程中调用函数
下一个博客讲怎么用互斥锁进行线程同步
//mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
extern int globalCount ;
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
qDebug()<<tr("主线程id:")<<QThread::currentThreadId();
//多线程方式1
myThread = new MyThread();//继承QThread
myThread->start();
//多线程方式2
myThread1 = new MyThread1();//继承QObject
thread1 = new QThread;
connect(thread1, SIGNAL(started()),myThread1, SLOT(doWork()));//个人推荐这种
myThread1->moveToThread(thread1);
thread1->start();
}
MainWindow::~MainWindow()
{
delete ui;
}
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "mythread.h"
#include <QThread>
#include <QObject>
#include <QTimer>
#include "mythread1.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
private:
Ui::MainWindow *ui;
MyThread *myThread;
MyThread1 *myThread1;
QThread *thread1 ;
};
#endif // MAINWINDOW_H
//方式1:只有run函数内的属于新的线程
//MyThread.cpp
#include "mythread.h"
extern int globalCount ;
MyThread::MyThread()
{
isStop = true;
}
void MyThread::closeThread()
{
isStop = true;
}
void MyThread::run()//只有run()里面在新的线程里
{
qDebug()<<tr("mythread QThread::currentThreadId()==")<<QThread::currentThreadId();
isStop = false;
//这种方式还是相当于在主线程里面执行
// timer= new QTimer(NULL);
// connect(timer, SIGNAL(timeout()), this, SLOT(onTimeout()));
// timer->start(1000);
// this->exec();
while(1)
{
if(isStop)
{
return;
}
qDebug()<<"globalCount: " << ++globalCount <<QThread::currentThreadId();
sleep(1);//QThread
}
}
//这种方式还是相当于在主线程里面执行
void MyThread::onTimeout()
{
qDebug()<<tr("mythread QThread::currentThreadId()==")<<QThread::currentThreadId();
qDebug()<<"globalCount: " << ++globalCount;
}
#ifndef MYTHREAD_H
#define MYTHREAD_H
#include <QObject>
#include <QThread>
#include <QDebug>
#include <QTimer>
class MyThread : public QThread
{
Q_OBJECT
public:
explicit MyThread();
void run();//重写基类的run函数
void closeThread();
signals:
public slots:
void onTimeout();
private:
QTimer * timer;
bool isStop = true;
};
#endif // MYTHREAD_H
#include "mythread1.h"
#include <QMutex>
extern QMutex mutex;
QMutex mutex1;
extern int globalCount ;
MyThread1::MyThread1(QObject *parent) : QObject(parent)
{
isStop = true;
}
void MyThread1::closeThread()
{
isStop = true;
}
void MyThread1::doWork()
{
qDebug()<<tr("mythread2 QThread::currentThreadId()==")<<QThread::currentThreadId();
isStop = false;
//定时方式1:(都是在子线程中)
timer= new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(onTimeout()));
timer->start(1000);
//定时方式2:(都是在子线程中)
// while(1)
// {
// if(isStop)
// {
// return;
// }
// QMutexLocker locker(&mutex);
// qDebug()<<"globalCount: " << ++globalCount <<QThread::currentThreadId();
// Sleep(1000);//<windows.h>,大写的S,单位是微秒
// }
}
void MyThread1::onTimeout()
{
QMutexLocker locker(&mutex1);
qDebug()<<"globalCount: " << ++globalCount <<QThread::currentThreadId();
}
#ifndef MYTHREAD1_H
#define MYTHREAD1_H
#include <QObject>
#include <QThread>
#include <QDebug>
#include <QTimer>
#include <windows.h>//Sleep(1);大写的S
class MyThread1 : public QObject
{
Q_OBJECT
public:
explicit MyThread1(QObject *parent = 0);
void closeThread();
signals:
public slots:
void doWork();
void onTimeout();
private:
QTimer * timer;
bool isStop = true;
};
#endif // MYTHREAD1_H