在本文中,我們將討論如何在 C++11 中停止或終止線程。
C++11 沒有提供停止正在運行的線程的直接方法,這是因為該線程可能有一些資源在退出前釋放或關閉,即
- 如果一個線程獲得了一個鎖,我們突然殺死了那個線程,那么誰來釋放那個鎖呢?
- 如果一個線程打開了一個文件來寫入文本,而我們停止了該線程,那么誰會關閉該文件呢?
- 如果線程已經在堆上分配了內存並且在它可以刪除該內存之前,我們會停止該線程。那么誰來防止內存泄漏。
因此沒有直接關閉線程的函數。但是我們可以通知線程退出,我們可以以這樣一種方式實現 out 線程,即在一段時間后或在某些檢查點后,它應該檢查是否要求我退出。如果是,那么它應該通過釋放所有資源優雅地退出。
使用 std::future<> 停止線程
我們可以將std::future<void>對象傳遞給線程,當未來的值可用時,線程應該退出。因為,我們只想給線程發信號,而不是在該信號中實際傳遞任何值,所以我們可以使用 void 類型的未來對象。
讓我們在 main 函數中創建一個 void 類型的 promise 對象,即
// 創建一個 std::promise 對象 std::promise < void > exitSignal;
現在,從主函數中的這個承諾中獲取關聯的未來對象,即
//獲取與promise關聯的std::future對象 std::future < void > futureObj = exitSignal.get_future () ;
現在在創建線程的主函數中,將未來對象傳遞給線程函數,即
// 啟動線程並通過引用移動 lambda 函數中的未來對象 std::thread th ( &threadFunction, std:: move ( futureObj )) ;
在線程內部,我們正在做一些工作並繼續檢查線程是否已被請求退出,即未來的值是否可用。
void threadFunction(std::future<void> futureObj) { std::cout << "Thread Start" << std::endl; while (futureObj.wait_for(std::chrono::milliseconds(1)) == std::future_status::timeout) { std::cout << "Doing Some Work" << std::endl; std::this_thread::sleep_for(std::chrono::milliseconds(1000)); } std::cout << "Thread End" << std::endl; }
一旦我們從 main 函數中設置了 promise 對象的值,未來對象中的值將在線程函數中可用,即
//設置promise中的值
exitSignal.set_value();
#include <thread> #include <iostream> #include <assert.h> #include <chrono> #include <future> void threadFunction(std::future<void> futureObj) { std::cout << "Thread Start" << std::endl; while (futureObj.wait_for(std::chrono::milliseconds(1)) == std::future_status::timeout) { std::cout << "Doing Some Work" << std::endl; std::this_thread::sleep_for(std::chrono::milliseconds(1000)); } std::cout << "Thread End" << std::endl; } int main() { // 創建一個 std::promise 對象 std::promise<void> exitSignal; //獲取與promise關聯的std::future 對象 std::future<void> futureObj = exitSignal.get_future(); // 啟動線程並且通過引用移動lambda函數中的未來對象 std::thread th(&threadFunction, std::move(futureObj)); //等待10秒 std::this_thread::sleep_for(std::chrono::seconds(10)); std::cout << "Asking Thread to Stop" << std::endl; //設置promise中的值 exitSignal.set_value(); //等待線程加入 th.join(); std::cout << "Exiting Main Function" << std::endl; return 0; }
Thread Start
Doing Some Work
Doing Some Work
Doing Some Work
Doing Some Work
Doing Some Work
Doing Some Work
Doing Some Work
Doing Some Work
Doing Some Work
Doing Some Work
Asking Thread to Stop
Thread End
Exiting Main Function
