参考:http://blog.csdn.net/rl529014/article/details/52815341
在上一篇文章中,转载了Qt创建多线程的两种方法,分别是继承QThread和继承QObject,文章较长,看得有点晕,但理论性比较全面,所以记录下来
本文通过最简单、最常用的方法,来实现多线程的创建,至于提到的其它问题,再慢慢优化吧
多线程的特点:
1、 多个线程共享进程的内存空间,多线程内存空间统一。
2、 每个线程都有自己独立的栈空间,多个线程之间是相互独立的。
3、 线程是操作系统运算调度的最小单位。
4、 进程支持多线程,但是必须有一个主线程。
5、 子线程都是通直接或者间接的通过主线程启动。
6、 主线程结束,所有子线程也会结束。
常用函数:
MoveToThread();
CurrentThread(),返回当前线程的指针。
CurrentThreadId(),返回当前线程的句柄。
生存线程:线程被创建时,该线程所在的线程。
注意:
多线程不是必须的,大多数情况下,一个主线程就可以完成相应的工作。
线程越多,对系统造成的负担越大。
实现多线程的方法:
1、Qthread(传统方法):继承自Qthread,实现run()函数,执行Qthread的start函数,线程开始执行。
2、Qtconcurrt(高级API,更加方便使用)
例:
下面以继承QThread,重写run()函数为例
功能:在主线程中创建两个子线程,点击start和stop分别开始和结束打印文本。
ui文件主界面:
先看效果图:
源码:
//main.cpp
-
#include <QApplication>
-
#include <QDebug>
-
#include "threaddialog.h"
-
#include <QThread>
-
int main(int argc, char *argv[])
-
{
-
QApplication a(argc, argv);
-
-
ThreadDialog dialog ;
-
dialog.show();
-
-
return a.exec();
-
}
//thread.h
-
#ifndef THREAD_H
-
#define THREAD_H
-
#include <QThread>
-
#include <QtCore>
-
#include <QObject>
-
#include <QMutex>
-
#include <iostream>
-
-
using
namespace
std;
-
-
class Thread :
public QThread
-
{
-
Q_OBJECT
-
public:
-
Thread();
-
-
void setMessage(const QString &message);
-
void stop();
-
-
private slots:
-
void run();
-
-
private:
-
QString messageStr;
-
volatile
bool stopped;
-
};
-
#endif // THREAD_H
//thread.cpp
-
#include "thread.h"
-
#include <QTimer>
-
#include <QMutexLocker>
-
-
Thread::Thread()
-
{
-
stopped =
false;
-
}
-
-
void Thread::setMessage(
const QString &message)
-
{
-
messageStr = message;
-
}
-
-
void Thread::stop()
-
{
-
stopped =
true;
-
}
-
-
void Thread::run()
-
{
-
while(!stopped)
-
{
-
qDebug()<<messageStr;
-
}
-
stopped =
false;
-
std::
cerr<<
std::
endl;
-
}
//threaddialog.h
-
#ifndef THREADDIALOG_H
-
#define THREADDIALOG_H
-
-
#include <QMainWindow>
-
#include "thread.h"
-
#include <QPushButton>
-
#include <QCloseEvent>
-
namespace Ui {
-
class ThreadDialog;
-
}
-
-
class ThreadDialog :
public QMainWindow
-
{
-
Q_OBJECT
-
-
public:
-
explicit ThreadDialog(QWidget *parent = 0);
-
~ThreadDialog();
-
-
protected:
-
void closeEvent(QCloseEvent *e);
-
-
private:
-
Thread threadA;
-
Thread threadB;
-
QPushButton *threadABtn;
-
QPushButton *threadBBtn;
-
QPushButton *quitBtn;
-
-
private slots:
-
void startOrStopThreadA();
-
void startOrStopThreadB();
-
void on_quit_clicked();
-
-
private:
-
Ui::ThreadDialog *ui;
-
};
-
-
#endif // THREADDIALOG_H
//threaddialog.cpp
-
#include "threaddialog.h"
-
#include "ui_threaddialog.h"
-
#include <QTimer>
-
-
ThreadDialog::ThreadDialog(QWidget *parent) :
-
QMainWindow(parent),
-
ui(
new Ui::ThreadDialog)
-
{
-
ui->setupUi(
this);
-
threadA.setMessage(
"I am A");
-
threadB.setMessage(
"I am B");
-
-
threadABtn =
new QPushButton(
"Start A");
-
threadBBtn =
new QPushButton(
"Start B");
-
quitBtn =
new QPushButton(
"Quit");
-
-
connect(ui->threadABtn,SIGNAL(clicked(
bool)),SLOT(startOrStopThreadA()));
-
connect(ui->threadBBtn,SIGNAL(clicked(
bool)),SLOT(startOrStopThreadB()));
-
}
-
-
ThreadDialog::~ThreadDialog()
-
{
-
delete ui;
-
}
-
-
void ThreadDialog::closeEvent(QCloseEvent *e)
-
{
-
threadA.stop();
-
threadB.stop();
-
threadA.wait();
-
threadB.wait();
-
e->accept();
-
}
-
-
void ThreadDialog::startOrStopThreadA()
-
{
-
if(threadA.isRunning())
-
{
-
threadA.stop();
-
ui->threadABtn->setText(
"Start A");
-
}
-
else
-
{
-
threadA.start();
-
ui->threadABtn->setText(
"Stop A");
-
}
-
}
-
-
void ThreadDialog::startOrStopThreadB()
-
{
-
if(threadB.isRunning())
-
{
-
threadB.stop();
-
ui->threadBBtn->setText(
"Start B");
-
}
-
else
-
{
-
threadB.start();
-
ui->threadBBtn->setText(
"Stop B");
-
}
-
}
-
-
void ThreadDialog::on_quit_clicked()
-
{
-
close();
-
}
源码下载:http://download.csdn.net/detail/rl529014/9657653