多线程是解决处理数据密集型的事件时,同时要需要响应用户的其它操作的一种很好的方法。并能够充分利用多处理器的优势。
(一)创建线程
(1)线程类
Qt 包含下面一些线程相关的类:
QThread 提供了开始一个新线程的方法;
QThreadStorage 提供线程数据存储;
QMutex 提供相互排斥的锁,或互斥量;
QMutexLocker 是一个方便类,它可以自动对QMutex加锁与解锁;
QReadWriterLock 提供了一个可以同时读写操作的锁
QReadLocker与QWriteLocker 是方便类,它自动对QReadWriteLock加锁与解锁
QSemaphore 提供了一个整型信号量,是互斥量的泛化
QWaitCondition 提供了一种方法,使得线程可以在被另外线程唤醒之前一直休眠。
Qt 高级线程类
QtConcurrent 开启线程事务
QFutureWatcher 观测线程状态
QFuture 线程启动类
(2)创建线程的方法
在QT应用程序中提供多线程是非常简单的,只需要子类化QThread并且重新实现它的run()函数就可以了。
class MyThread : public QThread { Q_OBJECT public: Thread(); protected: void run(); }; void MyThread::run() { ... }下面是一个简单的实例:
(1)首先使用QtCreater建立一个空工程multi_thread_test.pro;再分别建立3个cpp文件(create_thread.cpp,multi_thread.cpp,main.cpp)和2个.h文件(create_thread.h,multi_thread.h)。
//文件名称:create_thread.h
//文件描述:主要完成线程的子类化,以及其函数的定义
//=============== 以下是create_thread.h ============================
#ifndef CREATE_THREAD_H
#define CREATE_THREAD_H
#include <QThread>
//================================================================
class Thread:public QThread
{
Q_OBJECT
public:
Thread();
void setMessage(const QString &message);//向控制台打印数据
void stop();
protected:
void run();
private:
QString messageStr;//用于存放要打印的数据
volatile bool stopped;//易失性变量
};
#endif // CREATE_THREAD_H
=========================以下是multi_thread.h===============================
//文件名称:multi_thread.h
//文件描述:子类化一个dialog窗体,作为程序的界面
//注意事项:
#ifndef MULTI_THREAD_H
#define MULTI_THREAD_H
#include <QtGui>
#include <QDialog>
#include <QThread>
#include <create_thread.h>
class QPushButton;
class ThreadDialog : public QDialog
{
Q_OBJECT
public:
ThreadDialog (QWidget *parent = 0);
protected:
void closeEvent(QCloseEvent * event);
private slots:
void startOrStopThreadA();
void startOrStopThreadB();
private:
Thread threadA;
Thread threadB;
QPushButton *threadAButton;
QPushButton *threadBButton;
QPushButton *quitButton;
};
#endif // MULTI_THREAD_H
====================以下是create_thread.cpp=====================
//文件名称:create_thread.h
//文件描述:实例化线程子类
//注意事项:#include <iostream>
#include "create_thread.h"
//===========================================================
Thread :: Thread()
{
stopped = false;
}
//=============================================================
void Thread :: run()
{
while(!stopped)
std :: cerr << qPrintable(messageStr);
stopped = false;
std::cerr << std::endl;
}
//=============================================================
void Thread::stop()
{
stopped = true;
}
//=========================================================
void Thread::setMessage(const QString &message)
{
messageStr = message;
}
下面这个文件主要是建立主界面,一个dialog对话框,加上3个按钮;
=====================以下是multi_thread.cpp=========================
/*
*
*/
#include "multi_thread.h"
ThreadDialog :: ThreadDialog(QWidget *parent) : QDialog(parent)
{
threadA.setMessage("A");
threadB.setMessage("B");
threadAButton = new QPushButton(tr("start A"));
threadAButton->setVisible(true);
threadBButton = new QPushButton(tr("start B"));
threadBButton->show();
quitButton = new QPushButton(tr("quit"));
quitButton->setDefault(true);
QGridLayout *mainLayout = new QGridLayout;
mainLayout->addWidget(threadAButton,0,0);
mainLayout->addWidget(threadBButton,1,0);
mainLayout->addWidget(quitButton,2,0);
setLayout(mainLayout);
setWindowTitle(tr("Threads"));
connect(threadAButton,SIGNAL(clicked()),this, SLOT(startOrStopThreadA()));
connect(threadBButton,SIGNAL(clicked()),this, SLOT(startOrStopThreadB()));
}
//================================================================
void ThreadDialog::startOrStopThreadA()
{
if(threadA.isRunning())
{
threadA.stop();
threadAButton->setText(tr("start A"));
}else{
threadA.start();
threadAButton->setText(tr("stop A"));
}
}
//=================================================================
void ThreadDialog::startOrStopThreadB()
{
if(threadB.isRunning())
{
threadB.stop();
threadBButton->setText(tr("start B"));
}else{
threadB.start();
threadBButton->setText(tr("stop B"));
}
}
//============================================================
void ThreadDialog::closeEvent(QCloseEvent *event)
{
threadA.stop();
threadB.stop();
threadA.wait();
threadB.wait();
event->accept();
}
下面是主程序入口函数,这个文件没有什么好讲的。
===================以下是main.cpp=============================
#include <QApplication>
#include "multi_thread.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
ThreadDialog *threadDialog = new ThreadDialog;
threadDialog->show();
return app.exec();
}
=================================================================
-注意事项: