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 ¶meter) { 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 範例 , 信號量範例 ,和 等待條件範例 .
此枚舉類型指示操作係統應如何調度新近創建的綫程。
| 常量 | 值 | 描述 |
|---|---|---|
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 去管理新綫程。 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 文檔編製瞭解更多細節)。
[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).
返迴指針指嚮綫程的事件分派程序對象。若綫程不存在事件分派程序,此函數返迴
nullptr
.
該函數在 Qt 5.0 引入。
另請參閱 setEventDispatcher ().
[protected]
int
QThread::
exec
()
進入事件循環並等待,直到 exit () 被調用,返迴值被傳遞給 exit ()。返迴值為 0 若 exit () 被調用憑藉 quit ().
此函數意味著被調用從 run ()。它是必要的,去調用此函數以開始事件處理。
注意: 隻可以在綫程自身 (即:當它是當前綫程時) 內調用這。
告訴綫程的事件循環采用返迴代碼退齣。
在調用此函數之後,綫程離開事件循環並返迴從調用 QEventLoop::exec ()。 QEventLoop::exec () 函數返迴 returnCode .
按約定, returnCode 0 意味著成功,任何非零值指示齣錯。
注意:不像同名 C 庫函數,此函數 does 返迴給調用者 -- 它停止事件處理。
沒有 QEventLoop 會在此綫程中被再次啓動,直到 QThread::exec () 有被再次調用。若事件循環在 QThread::exec () 不在運行,則下一調用 QThread::exec () 也會立即返迴。
注意: 此函數是 綫程安全 .
另請參閱 quit () 和 QEventLoop .
[static]
int
QThread::
idealThreadCount
()
返迴可以在係統中運行的理想綫程數。這是通過查詢係統中實際和邏輯處理器核心數來完成的。此函數返迴 1,若無法檢測處理器核心數。
返迴
true
若綫程已完成;否則返迴
false
.
注意: 此函數是 綫程安全 .
另請參閱 isRunning ().
返迴 true,若在此綫程中正運行的任務應被停止。中斷可以被請求通過 requestInterruption ().
此函數可以用於使長時間運行的任務完全中斷。從不檢查 (或處理) 由此函數返迴的值是安全的,不管怎樣,建議在長時間運行函數中定期這樣做。當心不要太頻繁調用它,以保持較低開銷。
void long_task() { forever { if ( QThread::currentThread()->isInterruptionRequested() ) { return; } } }
注意: 隻可以在綫程自身 (即:當它是當前綫程時) 內調用這。
該函數在 Qt 5.2 引入。
另請參閱 currentThread () 和 requestInterruption ().
返迴
true
若綫程正在運行;否則返迴
false
.
注意: 此函數是 綫程安全 .
另請參閱 isFinished ().
返迴綫程的當前事件循環級彆。
注意: 隻可以在綫程自身 (即:當它是當前綫程時) 內調用這。
該函數在 Qt 5.5 引入。
[static]
void
QThread::
msleep
(
unsigned
long
msecs
)
強製當前綫程休眠 msecs 毫秒。
避免使用此函數,若需要等待給定條件改變。相反,可把槽連接到指示改變的信號或使用事件處理程序 (見 QObject::event ()).
注意: 此函數不保證準確性。應用程序可能休眠超過 msecs 在重負載條件下。某些 OS (操作係統) 可能圓整 msecs 到 10 ms 或 15 ms。
返迴正運行綫程的優先級。若綫程未在運行,此函數返迴
InheritPriority
.
該函數在 Qt 4.1 引入。
另請參閱 Priority , setPriority (),和 start ().
請求綫程的中斷。該請求是建議性的,且由在綫程上運行的代碼決定是否以及如何處理此請求。此函數不會停止在綫程中運行的任何事件循環,也不會以任何方式終止它。
注意: 此函數是 綫程安全 .
該函數在 Qt 5.2 引入。
另請參閱 isInterruptionRequested ().
[virtual protected]
void
QThread::
run
()
綫程的起點。先調用 start (),新近創建的綫程調用此函數。默認實現隻需調用 exec ().
可以重實現此函數以促進高級綫程管理。來自此方法的返迴將結束綫程的執行。
把綫程的事件分派程序設為 eventDispatcher 。這纔可能,隻要尚未為綫程安裝事件分派程序。也就是說,在啓動綫程之前采用 start (),或在主綫程情況下,先於 QCoreApplication 被實例化。此方法擁有對象的所有權。
該函數在 Qt 5.0 引入。
另請參閱 eventDispatcher ().
此函數設置 priority 為正運行綫程。若綫程未在運行,此函數什麼都不做並立即返迴。使用 start () 去啓動綫程采用特定優先級。
The
priority
自變量可以是任意值在
QThread::Priority
枚舉除瞭
InheritPriority
.
作用為 priority 參數從屬於操作係統的調度策略。尤其, priority 會被忽略,在不支持綫程優先級的係統中 (如在 Linux,見 http://linux.die.net/man/2/sched_setscheduler 瞭解更多細節)。
該函數在 Qt 4.1 引入。
另請參閱 Priority , priority (),和 start ().
把綫程的最大堆棧尺寸設為 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 在重負載條件下。
返迴綫程的最大堆棧尺寸 (若設置采用 setStackSize ());否則返迴 0。
另請參閱 setStackSize ().
[static]
void
QThread::
usleep
(
unsigned
long
usecs
)
強製當前綫程休眠 usecs 微秒。
避免使用此函數,若需要等待給定條件改變。相反,可把槽連接到指示改變的信號或使用事件處理程序 (見 QObject::event ()).
注意: 此函數不保證準確性。應用程序可能休眠超過 usecs 在重負載條件下。某些 OS (操作係統) 可能圓整 usecs 到 10 毫秒 (或 15 毫秒);在 Windows,它會被四捨五入到 1 毫秒的倍數。
阻塞綫程,直到滿足這些條件之一:
deadline (截止日期) 計時器設為
QDeadlineTimer::Forever
(默認) 將從不超時:在此情況下,函數纔返迴當綫程返迴從
run
() 或若綫程尚未啓動。
這提供的功能類似 POSIX
pthread_join()
函數。
該函數在 Qt 5.15 引入。
這是重載函數。
[static]
void
QThread::
yieldCurrentThread
()
把當前綫程的執行産生到另一可運行綫程,若有的話。注意:操作係統決定切換到哪個綫程。