QThread 類

QThread 類提供獨立於平颱的方式管理綫程。 更多...

頭: #include <QThread>
CMake: find_package(Qt6 REQUIRED COMPONENTS Core)
target_link_libraries(mytarget PRIVATE Qt6::Core)
qmake: QT += core
繼承: QObject

公共類型

enum Priority { IdlePriority, LowestPriority, LowPriority, NormalPriority, HighPriority, …, InheritPriority }
(從 6.9 起) 枚舉類 QualityOfService { Auto, High, Eco }

公共函數

QThread (QObject * parent = nullptr)
virtual ~QThread ()
QAbstractEventDispatcher * eventDispatcher () const
(從 6.8 起) bool isCurrentThread () const
bool isFinished () const
bool isInterruptionRequested () const
bool isRunning () const
int loopLevel () const
QThread::Priority priority () const
void requestInterruption ()
(從 6.9 起) QThread::QualityOfService serviceLevel () const
void setEventDispatcher (QAbstractEventDispatcher * eventDispatcher )
void setPriority (QThread::Priority priority )
(從 6.9 起) void setServiceLevel (QThread::QualityOfService serviceLevel )
void setStackSize (uint stackSize )
uint stackSize () const
bool wait (QDeadlineTimer deadline = QDeadlineTimer(QDeadlineTimer::Forever))
bool wait (unsigned long time )

重實現公共函數

virtual bool event (QEvent * event ) override

公共槽

void exit (int returnCode = 0)
void quit ()
void start (QThread::Priority priority = InheritPriority)
void terminate ()

信號

void finished ()
void started ()

靜態公共成員

QThread * create (Function && f , Args &&... args )
QThread * currentThread ()
Qt::HANDLE currentThreadId ()
int idealThreadCount ()
(從 6.8 起) bool isMainThread ()
void msleep (unsigned long msecs )
(從 6.6 起) void sleep (std::chrono::nanoseconds nsecs )
void sleep (unsigned long secs )
void usleep (unsigned long usecs )
void yieldCurrentThread ()

保護函數

int exec ()
virtual void run ()

靜態保護成員

void setTerminationEnabled (bool enabled = true)

詳細描述

QThread 對象管理程序中的某一控製綫程。QThread 的開始執行是在 run ()。默認情況下, run () 啓動事件循環通過調用 exec () 並在綫程內運行 Qt 事件循環。

可以使用 Worker 對象,通過把它們移到綫程使用 QObject::moveToThread ().

class Worker : public QObject
{
    Q_OBJECT
public slots:
    void doWork(const QString &parameter) {
        QString result;
        /* ... here is the expensive or blocking operation ... */
        emit resultReady(result);
    }
signals:
    void resultReady(const QString &result);
};
class Controller : public QObject
{
    Q_OBJECT
    QThread workerThread;
public:
    Controller() {
        Worker *worker = new Worker;
        worker->moveToThread(&workerThread);
        connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater);
        connect(this, &Controller::operate, worker, &Worker::doWork);
        connect(worker, &Worker::resultReady, this, &Controller::handleResults);
        workerThread.start();
    }
    ~Controller() {
        workerThread.quit();
        workerThread.wait();
    }
public slots:
    void handleResults(const QString &);
signals:
    void operate(const QString &);
};
					

然後,會在單獨綫程中執行 Worker 槽代碼。無論如何,把 Worker 槽連接到來自任何對象、任何綫程中的任何信號是自由的。跨不同綫程連接信號和槽是安全的,得益於機製 隊列連接 .

使在單獨綫程中運行代碼的另一方式,是子類化 QThread 並重實現 run ()。例如:

class WorkerThread : public QThread
{
    Q_OBJECT
public:
    explicit WorkerThread(QObject *parent = nullptr) : QThread(parent) { }
protected:
    void run() override {
        QString result;
        /* ... here is the expensive or blocking operation ... */
        emit resultReady(result);
    }
signals:
    void resultReady(const QString &s);
};
void MyObject::startWorkInAThread()
{
    WorkerThread *workerThread = new WorkerThread(this);
    connect(workerThread, &WorkerThread::resultReady, this, &MyObject::handleResults);
    connect(workerThread, &WorkerThread::finished, workerThread, &QObject::deleteLater);
    workerThread->start();
}
					

在該範例中,綫程會在 run 函數有返迴之後退齣。沒有任何事件循環會運行在綫程中,除非調用 exec ().

重要的是記住 QThread 實例 活在 實例化它的舊綫程,而不是新綫程調用 run ()。這意味著所有 QThread 的隊列槽和 援引方法 都將在舊綫程中執行。因此,希望在新綫程中援引槽的開發者,必須使用 worker-object 方式;新的槽不應被直接實現到 QThread 子類中。

不像隊列槽 (或援引方法),直接在 QThread 對象中被調用的方法,將在調用方法的綫程中執行。當子類化 QThread 時,請記住構造函數在舊綫程中執行而 run () 在新綫程中執行。若從兩者函數訪問成員變量,則變量是從 2 不同綫程被訪問。檢查這樣做是安全的。

注意: 當與跨不同綫程的對象交互時必須小心。作為一般規則,隻能從創建 QThread 對象本身的綫程調用函數 (如 setPriority ()),除非文檔編製另有說明。見 同步綫程 瞭解細節。

管理綫程

QThread 將憑藉信號通知您,當綫程 started () 和 finished (),或可以使用 isFinished () 和 isRunning () 去查詢綫程的狀態。

可以停止綫程通過調用 exit () 或 quit ()。在極端情況下,可能希望強製 terminate () 執行綫程。然而,這樣做是危險的且不鼓勵。請閱讀文檔編製為 terminate () 和 setTerminationEnabled () 瞭解詳細信息。

經常想要解除活在綫程中對象的分配,當綫程結束時。要做到這,連接 finished () 信號到 QObject::deleteLater ().

使用 wait () 去阻塞調用綫程,直到其它綫程已執行完成 (或直到指定時間已過去)。

QThread 還提供獨立於平颱的靜態休眠函數: sleep (), msleep (),和 usleep () 分彆允許完整秒、毫秒及微秒分辨率。

注意: wait () 和 sleep () 函數一般是不必要的,因為 Qt 是事件驅動型框架。代替 wait (),考慮監聽 finished () 信號。代替 sleep () 函數,考慮使用 QChronoTimer .

靜態函數 currentThreadId () 和 currentThread () 返迴目前正執行綫程的標識符。前者返迴特定平颱綫程 ID。後者返迴 QThread 指針。

要選取賦予綫程的名稱 (作為標識通過命令 ps -L 例如在 Linux),可以調用 setObjectName () 在啓動綫程之前。若不調用 setObjectName (),賦予綫程的名稱將是綫程對象運行時類型的類名 (例如, "RenderThread" 在案例 Mandelbrot 範例,作為 QThread 子類的名稱)。注意,目前這不可用於 Windows 發行構建。

另請參閱 Qt 多綫程 , QThreadStorage , 同步綫程 , Mandelbrot , 使用信號量的生産者和消費者 ,和 使用等待條件的生産者和消費者 .

成員類型文檔編製

enum QThread:: Priority

此枚舉類型指示操作係統應如何調度新近創建的綫程。

常量 描述
QThread::IdlePriority 0 纔調度,當沒有其它綫程在運行時。
QThread::LowestPriority 1 經常比 LowPriority 更少調度。
QThread::LowPriority 2 經常比 NormalPriority 更少調度。
QThread::NormalPriority 3 操作係統的默認優先級。
QThread::HighPriority 4 經常比 NormalPriority 更多調度。
QThread::HighestPriority 5 經常比 HighPriority 更多調度。
QThread::TimeCriticalPriority 6 盡可能經常調度。
QThread::InheritPriority 7 使用如創建綫程的相同優先級。這是默認。

[since 6.9] enum class QThread:: QualityOfService

This enum describes the quality of service level of a thread, and provides the scheduler with information about the kind of work that the thread performs. On platforms with different CPU profiles, or with the ability to clock certain cores of a CPU down, this allows the scheduler to select or configure a CPU core with suitable performance and energy characteristics for the thread.

常量 描述
QThread::QualityOfService::Auto 0 The default value, leaving it to the scheduler to decide which CPU core to run the thread on.
QThread::QualityOfService::High 1 The scheduler should run this thread to a high-performance CPU core.
QThread::QualityOfService::Eco 2 The scheduler should run this thread to an energy-efficient CPU core.

This enum was introduced in Qt 6.9.

另請參閱 Priority , serviceLevel (),和 QThreadPool::serviceLevel ().

成員函數文檔編製

[explicit] QThread:: QThread ( QObject * parent = nullptr)

構造新的 QThread 去管理新綫程。 parent 擁有 QThread 的所有權。綫程不會被執行直到 start () 被調用。

另請參閱 start ().

[virtual noexcept] QThread:: ~QThread ()

銷毀 QThread .

注意:刪除 QThread 對象不會停止其管理的綫程的執行。刪除正運行 QThread (即 isFinished () 返迴 false ) 會導緻程序崩潰。等待 finished () 信號先於刪除 QThread .

從 Qt 6.3 起,允許刪除 QThread 實例創建通過調用 QThread::create () 事件若相應綫程仍在運行。在這種情況下,Qt 會把中斷請求張貼給該綫程 (憑藉 requestInterruption ());將要求綫程的事件循環 (若有的話) 離開 (憑藉 quit ());且會阻塞直到綫程完成。

另請參閱 create (), isInterruptionRequested (), exec (),和 quit ().

[static] template <typename Function, typename... Args> QThread *QThread:: create ( 函數 && f , Args &&... args )

創建新的 QThread 對象以執行函數 f 采用自變量 args .

新綫程未啓動 – 它的啓動必須通過明確調用 start ()。這允許連接到其信號、把 QObject 移動到綫程、選擇新綫程的優先級、等等。函數 f 將在新綫程中被調用。

返迴新近創建的 QThread 實例。

注意: 調用者獲得所有權對於返迴的 QThread 實例。

警告: 不要調用 start () 在返迴的 QThread 實例超過一次;這樣做將産生未定義行為。

另請參閱 start ().

[static] QThread *QThread:: currentThread ()

返迴指針指嚮 QThread 由其管理目前正執行的綫程。

[static noexcept] Qt::HANDLE QThread:: currentThreadId ()

返迴目前執行綫程的綫程句柄。

警告: 由此函數返迴的句柄可以用於內部目的,且不應用於任何應用程序代碼中。

注意: 在 Windows,此函數返迴由 Win32 函數 GetCurrentThreadId() 返迴的 DWORD (Windows-Thread ID),而不是由 Win32 函數 GetCurrentThread() 返迴的僞 HANDLE (Windows-Thread HANDLE)。

[override virtual] bool QThread:: event ( QEvent * event )

重實現: QObject::event (QEvent *e).

QAbstractEventDispatcher *QThread:: eventDispatcher () const

返迴指針指嚮綫程的事件分派程序對象。若綫程不存在事件分派程序,此函數返迴 nullptr .

另請參閱 setEventDispatcher ().

[protected] int QThread:: exec ()

進入事件循環並等待,直到 exit () 被調用,返迴值被傳遞給 exit ()。返迴值為 0 若 exit () 被調用憑藉 quit ().

此函數意味著被調用從 run ()。它是必要的,去調用此函數以開始事件處理。

注意: 隻可以在綫程自身 (即:當它是當前綫程時) 內調用這。

另請參閱 quit () 和 exit ().

[slot] void QThread:: exit ( int returnCode = 0)

告訴綫程的事件循環采用返迴代碼退齣。

在調用此函數之後,綫程離開事件循環並返迴從調用 QEventLoop::exec ()。 QEventLoop::exec () 函數返迴 returnCode .

按約定, returnCode 0 意味著成功,任何非零值指示齣錯。

注意:不像同名 C 庫函數,此函數 does 會返迴給調用者 – 停止的是事件處理。

沒有 QEventLoop 會在此綫程中被再次啓動,直到 QThread::exec () 有被再次調用。若事件循環在 QThread::exec () 不在運行,則下一調用 QThread::exec () 也會立即返迴。

注意: 此函數是 綫程安全 .

另請參閱 quit () 和 QEventLoop .

[private signal] void QThread:: finished ()

從關聯綫程發射此信號,在剛好完成綫程執行前。

當發射此信號時,事件循環已停止運行。綫程沒有更多要處理的事件,除延期刪除事件外。可以將此信號連接到 QObject::deleteLater (),以釋放該綫程中的對象。

注意: 若關聯綫程的終止是使用 terminate (),從哪個綫程發射此信號未定義。

注意: 這是私有信號。它可以用於信號連接,但不能由用戶發射。

另請參閱 started ().

[static noexcept] int QThread:: idealThreadCount ()

返迴此進程可以並行運行的理想綫程數。這是通過查詢該進程的可用邏輯處理器數 (若 OS 支持) 或係統邏輯處理器的總數做到的。此函數返迴 1,若值無法確定。

注意: 在支持將綫程的傾嚮性設為所有邏輯處理器子集的操作係統,由此函數返迴的值可能隨綫程和時間改變。

注意: 在支持 CPU 熱插拔的操作係統,由此函數返迴的值也可能隨時間改變 (注意,CPU 可以通過軟件打開和關閉,不用改變物理硬件)。

[noexcept, since 6.8] bool QThread:: isCurrentThread () const

Returns true if this thread is QThread::currentThread .

該函數在 Qt 6.8 引入。

另請參閱 currentThreadId ().

bool QThread:: isFinished () const

返迴 true 若綫程已完成;否則返迴 false .

A thread is considered finished if it has returned from the run () function and the finished () 信號已發射。

Note the thread may still run for arbitrary amount of time after the finished () signal is emitted, running clean-up operations such as executing the destructors to thread_local variables. To synchronize with all effects from the thread, call wait () and verify it returned true.

注意: 此函數是 綫程安全 .

另請參閱 isRunning ().

bool QThread:: isInterruptionRequested () const

返迴 true,若在此綫程中正運行的任務應被停止。中斷可以被請求通過 requestInterruption ().

此函數可以用於使長時間運行的任務完全中斷。從不檢查 (或處理) 由此函數返迴的值是安全的,不管怎樣,建議在長時間運行函數中定期這樣做。當心不要太頻繁調用它,以保持較低開銷。

void long_task() {
     forever {
        if ( QThread::currentThread()->isInterruptionRequested() ) {
            return;
        }
    }
}
					

注意: 隻可以在綫程自身 (即:當它是當前綫程時) 內調用這。

另請參閱 currentThread () 和 requestInterruption ().

[static noexcept, since 6.8] bool QThread:: isMainThread ()

Returns whether the currently executing thread is the main thread.

The main thread is the thread in which QCoreApplication was created. This is usually the thread that called the main() function, but not necessarily so. It is the thread that is processing the GUI events and in which graphical objects ( QWindow , QWidget ) can be created.

該函數在 Qt 6.8 引入。

另請參閱 currentThread () 和 QCoreApplication::instance ().

bool QThread:: isRunning () const

返迴 true 若綫程正在運行;否則返迴 false .

A thread is considered to be running if QThread has been started with start () but is not yet finished.

Note the thread may still run for arbitrary amount of time after the finished () signal is emitted, running clean-up operations such as executing the destructors to thread_local variables. To synchronize with all effects from the thread, call wait () and verify it returned true.

注意: 此函數是 綫程安全 .

另請參閱 isFinished ().

int QThread:: loopLevel () const

返迴綫程的當前事件循環級彆。

注意: 隻可以在綫程自身 (即:當它是當前綫程時) 內調用這。

[static] void QThread:: msleep ( unsigned long msecs )

這是重載函數,相當於調用:

QThread::sleep(std::chrono::milliseconds{msecs});
					

注意: 此函數不保證準確性。應用程序可能休眠超過 msecs 在重負載條件下。某些 OS (操作係統) 可能圓整 msecs 到 10 ms 或 15 ms。

另請參閱 sleep () 和 usleep ().

QThread::Priority QThread:: priority () const

返迴正運行綫程的優先級。若綫程未在運行,此函數返迴 InheritPriority .

另請參閱 Priority , setPriority (),和 start ().

[slot] void QThread:: quit ()

告訴綫程的事件循環采用返迴代碼 0 (成功) 退齣。相當於調用 QThread::exit (0).

此函數什麼都不做,若綫程沒有事件循環。

注意: 此函數是 綫程安全 .

另請參閱 exit () 和 QEventLoop .

void QThread:: requestInterruption ()

請求綫程的中斷。該請求是建議性的,且由在綫程上運行的代碼決定是否以及如何處理此請求。此函數不會停止在綫程中運行的任何事件循環,也不會以任何方式終止它。

This function has no effect on the main thread, and does nothing if the thread is not currently running.

注意: 此函數是 綫程安全 .

另請參閱 isInterruptionRequested ().

[virtual protected] void QThread:: run ()

綫程的起點。先調用 start (),新近創建的綫程調用此函數。默認實現隻需調用 exec ().

可以重實現此函數以促進高級綫程管理。來自此方法的返迴將結束綫程的執行。

另請參閱 start () 和 wait ().

[since 6.9] QThread::QualityOfService QThread:: serviceLevel () const

Return the current Quality of Service level of the thread.

該函數在 Qt 6.9 引入。

另請參閱 setServiceLevel () 和 QThreadPool::serviceLevel ().

void QThread:: setEventDispatcher ( QAbstractEventDispatcher * eventDispatcher )

把綫程的事件分派程序設為 eventDispatcher 。這纔可能,隻要尚未為綫程安裝事件分派程序。

事件調度程序是自動創建的對於主綫程當 QCoreApplication 被實例化且當 start () 對於輔助綫程。

此方法擁有對象的所有權。

另請參閱 eventDispatcher ().

void QThread:: setPriority ( QThread::Priority priority )

此函數設置 priority 為正運行綫程。若綫程未在運行,此函數什麼都不做並立即返迴。使用 start () 去啓動綫程采用特定優先級。

The priority 自變量可以是任意值在 QThread::Priority 枚舉除瞭 InheritPriority .

作用為 priority 參數從屬於操作係統的調度策略。尤其, priority 會被忽略,在不支持綫程優先級的係統中 (如在 Linux,見 http://linux.die.net/man/2/sched_setscheduler 瞭解更多細節)。

另請參閱 Priority , priority (),和 start ().

[since 6.9] void QThread:: setServiceLevel ( QThread::QualityOfService serviceLevel )

Set the Quality of Service level of the thread object to serviceLevel . This can only be called from the thread itself or before the thread is started!

This is currently only implemented on Apple platforms, and Windows. The function call will complete successfully on other platforms but will not currently have any effect.

該函數在 Qt 6.9 引入。

另請參閱 serviceLevel () 和 QThreadPool::setServiceLevel ().

void QThread:: setStackSize ( uint stackSize )

將綫程的堆棧大小設為 stackSize 。若 stackSize 為 0,操作係統 (或運行時) 將選取默認值。否則,綫程堆棧大小將是提供值 (可以嚮上或嚮下四捨五入)。

在大多數操作係統,分配給堆棧服務的內存數量最初小於 stackSize 且會因綫程使用堆棧而增長。此參數設置允許增長到的最大大小 (即:它設置堆棧允許占據的虛擬內存空間大小)。

隻可以調用此函數,在啓動綫程之前。

警告: 大多數操作係統對綫程堆棧大小,有最小和最大限製。綫程將無法啓動,若堆棧大小超齣這些限製。

另請參閱 stackSize ().

[static protected] void QThread:: setTerminationEnabled ( bool enabled = true)

啓用 (或禁用) 當前綫程的終止,基於 enabled 參數。綫程必須已被啓動由 QThread .

enabled 為 false,終止被禁用。未來調用 QThread::terminate () 將立即返迴沒有效果。相反,終止被延期,直到終止被啓用。

enabled 為 true,終止被啓用。未來調用 QThread::terminate () 將正常終止綫程。若終止已被延期 (即: QThread::terminate () 被調用采用終止被禁用),此函數將終止調用綫程 immediately 。注意:此函數不會返迴,在此情況下。

另請參閱 terminate ().

[static, since 6.6] void QThread:: sleep ( std::chrono::nanoseconds nsecs )

強製當前綫程休眠 nsecs .

避免使用此函數,若需要等待給定條件改變。相反,可把槽連接到指示改變的信號或使用事件處理程序 (見 QObject::event ()).

注意: 此函數不保證準確性。應用程序可能休眠超過 nsecs 在重負載條件下。

該函數在 Qt 6.6 引入。

[static] void QThread:: sleep ( unsigned long secs )

強製當前綫程休眠 secs 秒。

這是重載函數,相當於調用:

QThread::sleep(std::chrono::seconds{secs});
					

另請參閱 msleep () 和 usleep ().

uint QThread:: stackSize () const

返迴綫程的最大堆棧尺寸 (若設置采用 setStackSize ());否則返迴 0。

另請參閱 setStackSize ().

[slot] void QThread:: start ( QThread::Priority priority = InheritPriority)

開始執行綫程通過調用 run ()。操作係統將調度綫程根據 priority 參數。若綫程已經在運行,此函數什麼都不做。

作用為 priority 參數從屬於操作係統的調度策略。尤其, priority 會被忽略,在不支持綫程優先級的係統中 (如在 Linux,見 sched_setscheduler 文檔編製瞭解更多細節)。

另請參閱 run () 和 terminate ().

[private signal] void QThread:: started ()

This signal is emitted from the associated thread when it starts executing, so any slots connected to it may be called via queued invocation. Whilst the event may have been posted before run () is called, any cross-thread delivery of the signal may still be pending.

注意: 這是私有信號。它可以用於信號連接,但不能由用戶發射。

另請參閱 run () 和 finished ().

[slot] void QThread:: terminate ()

終止綫程的執行。綫程可能 (或不可能) 被立即終止,取決於操作係統的調度策略。使用 QThread::wait () 在 terminate() 之後,來確保。

當綫程被終止時,等待綫程完成的所有綫程都將被喚醒。

警告: 此函數是危險的,且不鼓勵使用。綫程可以在其代碼路徑中的任何點被終止。綫程可以被終止,當修改數據時。綫程沒有機會在本身、解鎖任何保持互斥、等之後被清理。簡而言之,若絕對有必要纔使用此函數。

終止可以被明確啓用 (或禁用) 通過調用 QThread::setTerminationEnabled ()。當終止被禁用時,調用此函數會導緻終止被延期,直到終止被重新啓用。見文檔編製 QThread::setTerminationEnabled () 瞭解更多信息。

注意: 此函數是 綫程安全 .

另請參閱 setTerminationEnabled ().

[static] void QThread:: usleep ( unsigned long usecs )

這是重載函數,相當於調用:

QThread::sleep(std::chrono::microseconds{secs});
					

注意: 此函數不保證準確性。應用程序可能休眠超過 usecs 在重負載條件下。某些 OS (操作係統) 可能圓整 usecs 到 10 毫秒 (或 15 毫秒);在 Windows,它會被四捨五入到 1 毫秒的倍數。

另請參閱 sleep () 和 msleep ().

bool QThread:: wait ( QDeadlineTimer deadline = QDeadlineTimer(QDeadlineTimer::Forever))

阻塞綫程,直到滿足這些條件之一:

  • 關聯此綫程的 QThread 對象已執行完成 (即:當它返迴從 run ())。此函數將返迴 true,若綫程已完成。它也返迴 true,若綫程尚未被啓動。
  • The deadline 到達。此函數將返迴 false,若到達 deadline (最後期限)。

deadline (截止日期) 計時器設為 QDeadlineTimer::Forever (默認) 將從不超時:在此情況下,函數纔返迴當綫程返迴從 run () 或若綫程尚未啓動。

這提供的功能類似 POSIX pthread_join() 函數。

注意: On some operating systems, this function may return true while the operating system thread is still running and may be executing clean-up code such as C++11 thread_local destructors. Operating systems where this function only returns true after the OS thread has fully exited include Linux, Windows, and Apple operating systems.

另請參閱 sleep () 和 terminate ().

bool QThread:: wait ( unsigned long time )

time 是要等待的時間 (以毫秒為單位)。若 time 為 ULONG_MAX,則等待從不超時。

這是重載函數。

[static] void QThread:: yieldCurrentThread ()

把當前綫程的執行産生到另一可運行綫程,若有的話。注意:操作係統決定切換到哪個綫程。