- 統信UOS應用開發進階教程
- 統信軟件技術有限公司
- 1091字
- 2022-06-17 10:38:48
1.2 多線程的創建和管理
Qt通過3種形式提供對線程的支持,分別是平臺無關的線程類、線程安全的事件投遞、跨線程的信號槽連接。
Qt中主要的線程類如下。
● QThread:提供跨平臺的多線程解決方案。
● QThreadStorage:提供逐線程數據存儲。
● QMutex:提供相互排斥的鎖或互斥量。
● QMutexLocker:輔助類,可自動對 QMutex 加鎖與解鎖。
● QReadWriteLock:提供可以同時讀寫操作的鎖。
● QReadLocker與QWriteLocker:自動對QReadWriteLock 加鎖與解鎖。
● QSemaphore:提供整型信號量,是互斥量的泛化。
● QWaitCondition:線程在被其他線程喚醒之前一直休眠。
QThread是Qt線程中的一個公共的抽象類,所有的線程類都是從QThread抽象類中派生的。需要實現QThread中的虛函數run,可通過start函數來調用run函數。在默認情況下,QThread::run會啟動一個事件循環(QEventLoop::exec)。線程相關的函數如下。
● void run:線程體函數,用于定義線程的功能。
● void start:啟動函數,用于將線程入口地址設置為run函數。
● void terminate:用于強制結束線程,不保證數據完整性和資源釋放。
QCoreApplication::exec總是在主線程(執行main的線程)中被調用,不能從一個QThread中調用。在圖形用戶界面(GUI)程序中,主線程也稱為GUI線程,是唯一允許執行GUI相關操作的線程。另外,必須在創建一個QThread前創建QApplication(或QCoreApplication)對象。
當線程啟動和結束時,QThread會發送信號started和finished,可以使用isFinished和isRunning來查詢線程的狀態。
通過靜態函數currentThreadId和currentThread返回當前正在執行的線程的標識,前者返回線程的ID,后者返回一個線程指針。
如果要設置線程的名稱,可以在啟動線程之前調用setObjectName。如果不調用setObjectName函數,那么線程的名稱將是線程對象的運行時類型(QThread子類的類名)。
在新的線程中使用QThread類執行代碼可通過以下幾種方式。
1.繼承QThread類
重寫QThread的void run函數,在重寫的函數中添加需要執行的代碼。在以下代碼中,NewThread類通過繼承QThread類,重寫run函數,實現一個新的線程。
#include <QThread>
class NewThread : public QThread
{
public:
explicit NewThread(QObject *parent = 0);
protected:
void run()
{
// 具體語句
}
2.使用 QThread::create
使用 QThread::create(要求Qt版本至少為Qt 5.10)直接創建一個QThread對象,它可接收一個函數類型的參數,當調用QThread::start時會在新的線程中執行此函數。以下代碼為使用QThread::create函數的示例。
void function()
{
//具體語句
}
QThread *new_thread = QThread::create(function);
new_thread->start();
3.直接創建一個QThread對象
直接創建一個QThread對象,將一個QObject對象移動到此線程,則使用QMetaObject :: invokeMethod調用此對象的槽函數就會在新的線程中執行。以下代碼為使用moveToThread的示例。
class Object : public QObject
{
Q_OBJECT
public:
explicit Object(QObject *parent = nullptr);
public slots:
void function() {
//具體語句
}
};
QThread *new_thread = new QThread();
Object *object = new Object();
object->moveToThread(new_thread);//將對象交給線程
new_thread->start();
QMetaObject::invokeMethod(object, "function");
QRunnable類可以和QThreadPool(線程池)配合使用。和QThread的第一種使用方法類似,開發者也需要通過繼承并重寫QRunnable::run函數,從而在新的線程中執行代碼。以下代碼為使用QRunnable的示例。
class Runnable : public QRunnable
{
public:
void run() override
{
//具體語句
}
};
QRunnable *runnable = new Runnable();
runnable->setAutoDelete(runnable);
QThreadPool::globalInstance()->start(runnable);
QtConcurrent類是基于QRunnable封裝的上層接口,可以很方便地在一個新的線程中執行一個函數,也可以和QThreadPool配合使用,以滿足更靈活的功能需求。以下代碼為使用QtConcurrent的示例。
void function()
{
//具體語句
}
QtConcurrent::run(function);
- Mastering vRealize Operations Manager(Second Edition)
- Citrix XenApp Performance Essentials
- Implementing Cisco UCS Solutions
- 開源安全運維平臺OSSIM疑難解析:入門篇
- Installing and Configuring Windows 10:70-698 Exam Guide
- 深入Linux內核架構與底層原理(第2版)
- 移動應用UI設計模式(第2版)
- Microsoft Operations Management Suite Cookbook
- 嵌入式實時操作系統μC/OS原理與實踐
- 從實踐中學習Kali Linux無線網絡滲透測試
- Advanced TypeScript Programming Projects
- 新編電腦辦公(Windows 10+ Office 2013版)從入門到精通
- Windows 7使用詳解(修訂版)
- 鴻蒙HarmonyOS應用開發入門
- 操作系統之哲學原理第2版