這裏,只是記錄自己的學習筆記。
順便和大家分享多線程的基礎知識。然後從入門到實戰。有代碼。
知識點來源:
https://edu.51cto.com/course/26869.html
Promise 和 Future 的原理,以及演示
1 //線程異步和通信 2 3 4 /* 5 //promise 和 future 6 7 promise 用於異步傳輸變量 8 std::promise 提供存儲異步通信的值,再通過其對象創建的std::future異步獲得結果。 9 std::promise 只能使用一次。void set_value(_Ty&& _Val)設置傳遞值,只能調用一次 10 11 std::future 提供訪問異步操作結果的機制 12 get()阻塞等待 promise set_value 的值 13 14 */ 15 16 #include <iostream> 17 #include <thread> 18 #include <future> 19 #include <string> 20 using namespace std; 21 22 void TestFuture( promise<string> p){ 23 cout << "begin TestFuture" << endl; 24 25 this_thread::sleep_for(4s); 26 cout << "begin set value" << endl; 27 28 p.set_value("TestFuture value"); 29 this_thread::sleep_for(4s); 30 31 cout << "end TestFuture" << endl; 32 } 33 34 int main() { 35 //異步傳輸變量存儲 36 promise<string> p; 37 38 //用來獲取線程異步值 39 auto future = p.get_future(); 40 41 thread th(TestFuture, move(p)); 42 43 cout << "begin future.get()" << endl; 44 cout << "future get() =" << future.get() << endl;//線程在此處阻塞。等到 調用了 set_value 之後,阻塞取消。 45 cout << "end future.get()" << endl; 46 th.join(); 47 48 // begin future.get()...線程在此處阻塞。等到 調用了 set_value 之後,阻塞取消。 49 // begin TestFuture 50 // begin set value 51 // future get() = TestFuture value 52 // end future.get() 53 // end TestFuture 54 55 56 getchar(); 57 return 0; 58 }
packaged_task 異步調用函數打包
ackaged_task 包裝函數爲一個對象,用於異步調用。其返回值能通過 std::future() 對象訪問
與 bind 的區別,可異步調用,函數訪問和獲取返回值分開調用。
1 /* 2 packaged_task 異步調用函數打包 3 4 ackaged_task 包裝函數爲一個對象,用於異步調用。其返回值能通過 std::future() 對象訪問 5 與 bind 的區別,可異步調用,函數訪問和獲取返回值分開調用。 6 7 */ 8 9 10 // 函數指針 11 12 #include <iostream> 13 #include <thread> 14 #include <future> 15 #include <string> 16 17 using namespace std; 18 19 string TestPack(int index) { 20 cout << "begin Test Pack" << index << endl; 21 this_thread::sleep_for(3s); 22 return "Test Pack return "; 23 } 24 25 26 int main(int argc, char* argv[]) { 27 //同步 28 { 29 //// string(int) 是 TestPack 的函數指針 30 //packaged_task<string(int) > task(TestPack); 31 //auto result = task.get_future(); 32 //task(100); 33 34 //cout << "begin result get" << endl; 35 //cout << "result get: " << result.get() << endl; 36 ////result.get()是阻塞的 37 } 38 39 40 //異步 41 { 42 // string(int) 是 TestPack 的函數指針 43 packaged_task<string(int) > task(TestPack); 44 auto result = task.get_future(); 45 //task(100); 46 thread th(move(task), 102); 47 cout << "begin result get " << endl; 48 // get()是阻塞,會等待函數返回。。 49 cout << "result get: " << result.get() << endl; 50 th.join(); 51 } 52 53 54 //異步 55 { 56 // string(int) 是 TestPack 的函數指針 57 packaged_task<string(int) > task(TestPack); 58 auto result = task.get_future(); 59 //task(100); 60 thread th(move(task), 103); 61 cout << "begin result get " << endl; 62 63 for (int i = 0; i < 30; i++) { 64 if (result.wait_for(100ms) != future_status::ready) { 65 continue; 66 } 67 } 68 if (result.wait_for(100ms) == future_status::timeout) { 69 cout << "wait result timeout" << endl; 70 } 71 else{ 72 cout << "result get: " << result.get() << endl; 73 } 74 th.join(); 75 } 76 77 getchar(); 78 return 0; 79 }
async
C++ 異步運行一個函數,並返回保有其結果的 std::future
1.launch::deferred 延遲執行,在調用 wait 和 get 時,調用函數代碼。
2.launch::async 創建線程(默認)
3.返回的線程函數的返回值類型的std::future<int> (std::future<線程函數的返回值類型>)
4.re.get() 獲取結果,會阻塞等待。
1 /* 2 async 3 C++ 異步運行一個函數,並返回保有其結果的 std::future 4 5 1.launch::deferred 延遲執行,在調用 wait 和 get 時,調用函數代碼。 6 2.launch::async 創建線程(默認) 7 3.返回的線程函數的返回值類型的std::future<int> (std::future<線程函數的返回值類型>) 8 4.re.get() 獲取結果,會阻塞等待。 9 */ 10 11 #include <iostream> 12 #include <thread> 13 #include <future> 14 #include <string> 15 16 using namespace std; 17 18 string TestAsync(int index) { 19 cout << index<< " begin in TestAsync " << this_thread::get_id() << endl; 20 this_thread::sleep_for(2s); 21 return "TestAsync string return"; 22 } 23 24 25 int main() { 26 //創建異步線程 27 28 { 29 //不創建線程,啓動異步任務 30 //cout << "main thread id: " << this_thread::get_id() << endl; 31 //auto future = async(launch::deferred, TestAsync, 100); 32 //this_thread::sleep_for(50ms); 33 //cout << "begin future get " << endl; 34 //cout << "future.get() = " << future.get() << endl;//調用get函數的時候,纔開始執行TestAsync方法 35 //cout << "end future get " << endl; 36 } 37 38 { 39 //創建異步線程 40 cout << "=======創建異步線程=========mainThreadId:"<<this_thread::get_id() << endl; 41 auto future2 = async(TestAsync, 102); 42 this_thread::sleep_for(50ms); 43 cout << "begin future2 get " << endl; 44 cout << "future2.get() = " << future2.get() << endl; 45 cout << "end future2 get " << endl; 46 } 47 48 getchar(); 49 return 0; 50 }