C++多线程编程第九讲--async、future、packaged_task、promise
//(1)std::async、 std::future创建后台任务并返回值
// async是一个函数模板,用来启动一个异步任务,返回一个future类型的对象。用future
// 的get方法来获得线程的返回值。
// 异步任务:自动创建一个线程,并开始执行对应线程的入口函数。
#include<iostream>
#include<mutex>
#include<thread>
#include<future>
using namespace std;
int my_thread()
{
cout << "my_thread start... " << "thread id = " << this_thread::get_id() << endl;
std::chrono::milliseconds duro(5000);
std::this_thread::sleep_for(duro);
cout << "my_thread end... " << "thread id = " << this_thread::get_id() << endl;
return 5;
}
int main()
{
cout << "main() start... " << "thread id = " << std::this_thread::get_id() << endl;
std::future<int> result = std::async(my_thread);
cout << result.get() << endl; //主线程会在get这里一致等到新的线程返回结果
//cout << result.get() << endl; //不能调用多次,调用多次会报异常
//result.wait(); //等待新的线程执行结束,但并不会储存返回值。
cout << "main() end... " << "thread id = " << std::this_thread::get_id() << endl;
return 0;
}
#include<iostream>
#include<mutex>
#include<thread>
#include<future>
using namespace std;
class A
{
public:
int my_thread(int mypar)
{
cout << "my_thread start... " << "thread id = " << this_thread::get_id() << endl;
std::chrono::milliseconds duro(5000);
std::this_thread::sleep_for(duro);
cout << "my_thread end... " << "thread id = " << this_thread::get_id() << endl;
return mypar;
}
};
int main()
{
A myobja;
cout << "main() start... " << "thread id = " << std::this_thread::get_id() << endl;
std::future<int> result = std::async(&A::my_thread, std::ref(myobja), 5);
//主线程会在get这里一致等到新的线程返回结果,如果没有这一句的话
//在主线程return的时候,会等待新的线程执行结束。
cout << result.get() << endl;
//cout << result.get() << endl; //不能调用多次,调用多次会报异常
//result.wait(); //等待新的线程执行结束,但并不会储存返回值。
cout << "main() end... " << "thread id = " << std::this_thread::get_id() << endl;
return 0;
}
// 可以额外向std::async()传递一个参数,参数类型是std::lunch类型(枚举)。
// std::launch::deferred 新线程执行时间延迟到调用wait或者get时才执行(创建)
#include<iostream>
#include<mutex>
#include<thread>
#include<future>
using namespace std;
class A
{
public:
int my_thread(int mypar)
{
cout << "my_thread start... " << "thread id = " << this_thread::get_id() << endl;
std::chrono::milliseconds duro(5000);
std::this_thread::sleep_for(duro);
cout << "my_thread end... " << "thread id = " << this_thread::get_id() << endl;
return mypar;
}
};
int main()
{
A myobja;
cout << "main() start... " << "thread id = " << std::this_thread::get_id() << endl;
//新线程延迟到调用wait或者get的时候再启动,但使用std::launch::deferred这个参数
//直接没有创建新的线程,在主线程中调用的入口函数。
std::future<int> result = std::async(std::launch::deferred, &A::my_thread, std::ref(myobja), 5);
//主线程会在get这里一致等到新的线程返回结果,如果没有这一句的话
//在主线程return的时候,会等待新的线程执行结束。
cout << result.get() << endl; //在主线程中执行。
//cout << result.get() << endl; //不能调用多次,调用多次会报异常
//result.wait(); //等待新的线程执行结束,但并不会储存返回值。
cout << "main() end... " << "thread id = " << std::this_thread::get_id() << endl;
return 0;
}
// std::launch::async 在调用async这个函数的时候即开始创建新的线程,执行入口函数。默认async方法的第一个参数
//就是std::launch::async
//
//(2)std::packaged_task 是个模板类,将各种可调用对象包装起来。
#include<iostream>
#include<mutex>
#include<thread>
#include<future>
using namespace std;
int my_thread(int mypar)
{
cout << "my_thread start... " << "thread id = " << this_thread::get_id() << endl;
std::chrono::milliseconds duro(5000);
std::this_thread::sleep_for(duro);
cout << "my_thread end... " << "thread id = " << this_thread::get_id() << endl;
return mypar;
}
int main()
{
cout << "main() start... " << "thread id = " << std::this_thread::get_id() << endl;
std::packaged_task<int(int)> mypt(my_thread); //把函数my_thread包装起来
std::thread t1(std::ref(mypt), 5); //用一个package_task对象作为线程的参数
t1.join();
std::future<int> result = mypt.get_future();
cout << result.get() << endl; //打印返回的结果
cout << "main() end... " << "thread id = " << std::this_thread::get_id() << endl;
return 0;
}
#include<iostream>
#include<mutex>
#include<thread>
#include<future>
using namespace std;
int main()
{
cout << "main() start... " << "thread id = " << std::this_thread::get_id() << endl;
//包装lamda表达式
std::packaged_task<int(int)> mypt([](int mypar)
{
cout << "my_thread start... " << "thread id = " << this_thread::get_id() << endl;
std::chrono::milliseconds duro(5000);
std::this_thread::sleep_for(duro);
cout << "my_thread end... " << "thread id = " << this_thread::get_id() << endl;
return mypar;
}
);
std::thread t1(std::ref(mypt), 5); //用一个package_task对象作为线程的参数
t1.join();
std::future<int> result = mypt.get_future();
cout << result.get() << endl; //打印返回的结果
cout << "main() end... " << "thread id = " << std::this_thread::get_id() << endl;
return 0;
}
#include<iostream>
#include<mutex>
#include<thread>
#include<future>
using namespace std;
int main()
{
cout << "main() start... " << "thread id = " << std::this_thread::get_id() << endl;
//包装lamda表达式
std::packaged_task<int(int)> mypt([](int mypar)
{
cout << "my_thread start... " << "thread id = " << this_thread::get_id() << endl;
std::chrono::milliseconds duro(5000);
std::this_thread::sleep_for(duro);
cout << "my_thread end... " << "thread id = " << this_thread::get_id() << endl;
return mypar;
}
);
mypt(5); //不创建新的线程,直接调用也可以。
std::future<int> result = mypt.get_future();
cout << result.get() << endl; //打印返回的结果
cout << "main() end... " << "thread id = " << std::this_thread::get_id() << endl;
return 0;
}
#include<iostream>
#include<mutex>
#include<thread>
#include<future>
#include<vector>
using namespace std;
vector<std::packaged_task<int(int)>> mytasks;
int main()
{
cout << "main() start... " << "thread id = " << std::this_thread::get_id() << endl;
//包装lamda表达式
std::packaged_task<int(int)> mypt([](int mypar)
{
cout << "my_thread start... " << "thread id = " << this_thread::get_id() << endl;
std::chrono::milliseconds duro(5000);
std::this_thread::sleep_for(duro);
cout << "my_thread end... " << "thread id = " << this_thread::get_id() << endl;
return mypar;
}
);
mytasks.push_back(std::move(mypt)); //使用移动语义
std::packaged_task<int(int)> mypt2;
auto iter = mytasks.begin();
mypt2 = std::move(*iter);
mytasks.erase(iter); //迭代器失效,后面不可以使用iter
mypt2(123);
std::future<int> result = mypt2.get_future();
cout << result.get() << endl;
cout << "main() end... " << "thread id = " << std::this_thread::get_id() << endl;
return 0;
}
//(3)std::promise
// 我们可以在某个线程中给他赋值,在其他线程中把这个值取出来。
#include<iostream>
#include<mutex>
#include<thread>
#include<future>
#include<vector>
#include<memory>
using namespace std;
void my_thread(std::promise<int>& tmp, int calc)
{
cout << "my_thread start..." << endl;
cout << "my_thread id = " << std::this_thread::get_id() << endl;
cout << calc << endl;
std::chrono::milliseconds duro(5000); //休眠5秒,模拟计算过程
std::this_thread::sleep_for(duro);
int result = calc;
tmp.set_value(result); //将结果保存到promise的对象中
cout << "my_thread end..." << endl;
}
void my_thread2(std::future<int>& tmpf)
{
cout << "my_thread2 start..." << endl;
cout << "thread id = " << std::this_thread::get_id() << endl;
cout << tmpf.get() << endl; //获得另外一个线程传过来的值
cout << "my_thread2 end..." << endl;
}
int main()
{
cout << "main() start... " << "thread id = " << std::this_thread::get_id() << endl;
std::promise<int> result;
//std::thread t1(my_thread, result, 123); //错误
std::thread t1(my_thread, std::ref(result), 123); //使用ref来传递,不能直接赋值对象。
auto fut = result.get_future();
std::thread t2(my_thread2, std::ref(fut));
t1.join();
t2.join();
cout << "main() end... " << "thread id = " << std::this_thread::get_id() << endl;
return 0;
}
posted on 2021-10-21 23:12 xcxfury001 阅读(97) 评论(0) 收藏 举报
浙公网安备 33010602011771号