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 }