做了一个demo展示两种形式的多线程操作,第二种常用
- new QThread Class & Override run()
- new Object Class & moveToThread(new QThread)
// threadfirst.h 第一种形式的线程操作
#ifndef THREADFIRST_H
#define THREADFIRST_H
#include <QThread>
#include <QObject>
class ThreadFirst : public QThread
{
Q_OBJECT
public:
explicit ThreadFirst(QObject *parent = nullptr);
~ThreadFirst();
protected:
void run();
signals:
void finish(const QString &str);
};
#endif // THREADFIRST_H
// threadfirst.cpp
#include "threadfirst.h"
#include <QDebug>
ThreadFirst::ThreadFirst(QObject *parent) : QThread(parent)
{
}
ThreadFirst::~ThreadFirst()
{
}
void ThreadFirst::run()
{
sleep(2);
QString str = "threadFirst is finished";
emit finish(str);
}
// threadsec.h 第二种形式的线程操作
#ifndef THREADSEC_H
#define THREADSEC_H
#include <QObject>
#include <QTimer>
class ThreadSec : public QObject
{
Q_OBJECT
public:
explicit ThreadSec();
~ThreadSec();
void stopTimer();
signals:
void finish();
private slots:
void handleThread();
private:
QTimer sigTimer; // 延时发出信号
};
#endif // THREADSEC_H
// threadsec.cpp
#include "threadsec.h"
ThreadSec::ThreadSec()
{
connect(&sigTimer, &QTimer::timeout, this, &ThreadSec::handleThread);
sigTimer.start(3000);
}
ThreadSec::~ThreadSec()
{
}
void ThreadSec::handleThread()
{
emit finish();
}
void ThreadSec::stopTimer()
{
sigTimer.stop();
}
主窗口类
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "threadfirst.h"
#include "threadsec.h"
#include <QThread>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_btnFirst_clicked();
void on_btnSec_clicked();
private:
Ui::MainWindow *ui;
ThreadFirst *_threadFirst = nullptr;
ThreadSec *_threadSec = nullptr;
QThread *_thread = nullptr;
};
#endif // MAINWINDOW_H
///
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
_threadFirst->quit();
_threadFirst->wait();
_thread->quit();
_thread->wait();
delete ui;
}
void MainWindow::on_btnFirst_clicked()
{
_threadFirst = new ThreadFirst();
connect(_threadFirst, &ThreadFirst::finished, _threadFirst, &QObject::deleteLater);
connect(_threadFirst, &ThreadFirst::finish, this, [=] (QString str) {
ui->lcdNumber->display(99);
qDebug() << str;
});
_threadFirst->start();
}
void MainWindow::on_btnSec_clicked()
{
int i = 0;
_threadSec = new ThreadSec();
_thread = new QThread();
_threadSec->setObjectName("second use");
_threadSec->moveToThread(_thread);
connect(_thread, &QThread::finished, _threadSec, &QObject::deleteLater);
connect(_threadSec, &ThreadSec::finish, this, [=] () mutable {
ui->lcdNumber->display(i++);
if (i >= 10) _threadSec->stopTimer();
qDebug() << "threadSec is finished";
});
_thread->start();
}
- 问题:关于多线程同时访问同一个函数
每个线程都有自己的栈区存放局部变量,不同线程调用函数的局部变量,保存在不同线程的栈区中,这种情况不需要进行互斥处理。
需要进行互斥处理的情况通常是,函数中有全局变量,有动态申请的空间,静态变量,成员变量,或者是线程需要进行循环发送读取操作。