C++多線程-chap3 多線程異步和通信-1

這裏,只是記錄自己的學習筆記。

順便和大家分享多線程的基礎知識。然後從入門到實戰。有代碼。

知識點來源:

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 }

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章