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 
17 #include 
18 #include 
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 
13 #include 
14 #include 
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  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 (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 (std::future<线程函数的返回值类型>)
 8 4.re.get() 获取结果,会阻塞等待。
 9 */
10 
11 #include 
12 #include 
13 #include 
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:"< 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 }