QThread 類

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

頭: #include <QThread>
qmake: QT += core
繼承: QObject

公共類型

enum Priority { IdlePriority, LowestPriority, LowPriority, NormalPriority, HighPriority, …, InheritPriority }

公共函數

QThread (QObject * parent = nullptr)
virtual ~QThread ()
QAbstractEventDispatcher * eventDispatcher () const
void exit (int returnCode = 0)
bool isFinished () const
bool isInterruptionRequested () const
bool isRunning () const
int loopLevel () const
QThread::Priority priority () const
void requestInterruption ()
void setEventDispatcher (QAbstractEventDispatcher * eventDispatcher )
void setPriority (QThread::Priority priority )
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 quit ()
void start (QThread::Priority priority = InheritPriority)
void terminate ()

信號

void finished ()
void started ()

靜態公共成員

QThread * create (Function && f , Args &&... args )
QThread * create (Function && f )
QThread * currentThread ()
Qt::HANDLE currentThreadId ()
int idealThreadCount ()
void msleep (unsigned long msecs )
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
    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 () 瞭解詳細信息。

從 Qt 4.8 起,解除活在剛結束綫程中對象的分配是可能的,通過連接 finished () 信號到 QObject::deleteLater ().

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

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

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

靜態函數 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 使用如創建綫程的相同優先級。這是默認。

成員函數文檔編製

QThread:: QThread ( QObject * parent = nullptr)

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

另請參閱 start ().

[signal] void QThread:: finished ()

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

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

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

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

另請參閱 started ().

[slot] void QThread:: quit ()

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

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

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

另請參閱 exit () 和 QEventLoop .

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

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

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

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

[signal] void QThread:: started ()

從關聯綫程此信號發射,當開始執行時,先於 run () 函數被調用。

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

另請參閱 finished ().

[slot] void QThread:: terminate ()

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

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

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

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

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

另請參閱 setTerminationEnabled ().

[虛擬] QThread:: ~QThread ()

銷毀 QThread .

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

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

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

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

返迴新近創建的 QThread 實例。

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

注意: 此函數隻可用於使用 C++17 時。

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

該函數在 Qt 5.10 引入。

另請參閱 start ().

[static] template <typename Function> QThread *QThread:: create ( Function && f )

創建新的 QThread 對象以執行函數 f .

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

返迴新近創建的 QThread 實例。

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

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

該函數在 Qt 5.10 引入。

另請參閱 start ().

[static] QThread *QThread:: currentThread ()

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

[static] 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 .

該函數在 Qt 5.0 引入。

另請參閱 setEventDispatcher ().

[protected] int QThread:: exec ()

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

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

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

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

void QThread:: exit ( int returnCode = 0)

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

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

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

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

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

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

另請參閱 quit () 和 QEventLoop .

[static] int QThread:: idealThreadCount ()

返迴可以在係統中運行的理想綫程數。這是通過查詢係統中實際和邏輯處理器核心數來完成的。此函數返迴 1,若無法檢測處理器核心數。

bool QThread:: isFinished () const

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

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

另請參閱 isRunning ().

bool QThread:: isInterruptionRequested () const

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

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

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

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

該函數在 Qt 5.2 引入。

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

bool QThread:: isRunning () const

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

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

另請參閱 isFinished ().

int QThread:: loopLevel () const

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

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

該函數在 Qt 5.5 引入。

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

強製當前綫程休眠 msecs 毫秒。

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

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

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

QThread::Priority QThread:: priority () const

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

該函數在 Qt 4.1 引入。

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

void QThread:: requestInterruption ()

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

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

該函數在 Qt 5.2 引入。

另請參閱 isInterruptionRequested ().

[virtual protected] void QThread:: run ()

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

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

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

void QThread:: setEventDispatcher ( QAbstractEventDispatcher * eventDispatcher )

把綫程的事件分派程序設為 eventDispatcher 。這纔可能,隻要尚未為綫程安裝事件分派程序。也就是說,在啓動綫程之前采用 start (),或在主綫程情況下,先於 QCoreApplication 被實例化。此方法擁有對象的所有權。

該函數在 Qt 5.0 引入。

另請參閱 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 瞭解更多細節)。

該函數在 Qt 4.1 引入。

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

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] void QThread:: sleep ( unsigned long secs )

強製當前綫程休眠 secs 秒。

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

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

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

uint QThread:: stackSize () const

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

另請參閱 setStackSize ().

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

強製當前綫程休眠 usecs 微秒。

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

注意: 此函數不保證準確性。應用程序可能休眠超過 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() 函數。

該函數在 Qt 5.15 引入。

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

bool QThread:: wait ( unsigned long time )

這是重載函數。

[static] void QThread:: yieldCurrentThread ()

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