C++11 并发与多线程(九、async,future,packged_task,promise)

一、std::async,std::future创建后台任务并返回值

  1. std::async 是个函数模板,用来启动一个异步任务,启动之后, 返回一个std::future对象;
  2. std::future是个类模板(异步任务:就是自动创建一个线程并开始执行对应的入口函数,它返回一个std::future 对象(线程返回结果),我们可以通过调用future对象成员函数get()来获取结果)
  3. std::future 提供了一种访问异步操作结果的机制
  4. std::future 的 get() 函数,等待线程运行结束,拿到结果 ,只能调用一次,不能调用多次
#include <mutex>
#include <future>
using namespace std;

//线程入口函数
int MyThread()
{
	cout << "MyThread Start " << "thread id = " << std::this_thread::get_id() << endl;

	this_thread::sleep_for(std::chrono::milliseconds(5000));	//线程休息5秒

	cout << "MyThread End " << "thread id = " << this_thread::get_id() << endl;

	return 5;
}

int main()
{
	cout << "main thread id" << this_thread::get_id() << endl;
	
	future<int> result = std::async(MyThread);	//创建一个线程并开始执行,流程并不会卡到这里
	//也可以用类的成员函数作为线程让你口函数
	//Test obj;
	//future<int> result = std::async(&Test::MyThread, &obj,25);	//默认第一个参数是调用std::launch::async
	cout << "contine..." << endl;
	
	cout << result.get() << endl;	//卡在这里等待MyThread()执行完毕,拿到结果
	//result.wait()   等待线程返回,本身并不会返回结果
	cout << "I Love China" << endl;
    return 0;
}
  1. future 里面的 wait()函数:等待线程返回,本身并不会返回结果。
  2. 通过额外向std::async()传递一个参数,该参数是std::lunnch类型(枚举类型)。
    6.1 std::lannch::deferred : 表示线程入口函数调用被延迟到std::future的wait()或者get()函数调用时才执行;此时如果没有调用wait()或者get()函数,线程就根本不会创建,线程函数就不会被调用。
    6.2 std::lannch::deferred : 延迟调用,并没有创建新线程(线程ID一样),是在主线程中调用的入口函数。
Test obj;
future<int> result = std::async(std::launch::deferred,&Test::MyThread, &obj,25);

6.3 在调用async函数的时候就开始创建线程,不传参数时,默认值是:std::launch::async | std::launch::deferred两者合二为一,系统会自行决定是异步(创建新线程)还是同步(不创建新线程)方式运行

Test obj;
future<int> result = std::async(std::launch::async,&Test::MyThread, &obj,25);

二、std::packged_task 打包任务

  1. std::packged_task: 是个类模板,它的模板参数是各种调用对象,方便将来作为线程入口函数

重要代码部分:

//int(int) 代表是线程入口函数的参数和返回值 
std::packaged_task<int(int)> myPt(MyThread);	//将线程入口函数包装起来
std::thread obj(std::ref(myPt), 2);	//线程开始执行
obj.join();
std::future<int> result = myPt.get_future();	//std::future对象里面有线程入口函数的返回结果,这里result保存返回的结果

完整代码演示:

//线程入口函数
int MyThread(int num)
{
	cout << num << endl;
	cout << "MyThread Start " << "thread id = " << std::this_thread::get_id() << endl;

	this_thread::sleep_for(std::chrono::milliseconds(5000));	//线程休息5秒

	cout << "MyThread End " << "thread id = " << this_thread::get_id() << endl;

	return 5;
}
int main()
{
	cout << "main thread id = " << this_thread::get_id() << endl;

	std::packaged_task<int(int)> myPt(MyThread);	//将线程入口函数包装起来
	std::thread obj(std::ref(myPt), 2);	//线程开始执行
	obj.join();
	std::future<int> result = myPt.get_future();	//std::future对象里面有线程入口函数的返回结果,这里result保存返回的结果
	cout << result.get() << endl;

	cout << "I Love China" << endl;
    return 0;
}

也可以用lambd表达式作为可调用对象

int main()
{
	std::packaged_task<int(int)> mypt([](int pair) {
	cout << pair << endl;
	cout << "MyThread Start " << "thread id = " << std::this_thread::get_id() << endl;

	this_thread::sleep_for(std::chrono::milliseconds(5000));	//线程休息5秒

	cout << "MyThread End " << "thread id = " << this_thread::get_id() << endl;

	return 5;
	});
	std::thread obj(std::ref(mypt), 2);	//线程开始执行
	obj.join();
	//mypt(10) //也可以直接调用 但是这种是不会创建新的线程
	std::future<int> result = mypt.get_future();	//std::future对象里面有线程入口函数的返回结果,这里result保存返回的结果
	cout << result.get() << endl;

	cout << "I Love China" << endl;
    return 0;
}

三、std::promise 类模板

1.作用:能在某个线程中给它赋值,然后可以在其他线程中把值取出来使用

//线程入口函数
void MyThread(std::promise<int> &temp,int calc)
{
	//做一些列的运算
	calc++;
	calc *= 10;
	//其他计算,比如花费了5秒中
	std::this_thread::sleep_for(std::chrono::milliseconds(5000));
	//保存结果
	temp.set_value(calc);
}
void MyThread1(std::future<int> &temp)
{
	auto result = temp.get();
	cout << "Result = " << result << endl;
}
int main()
{
	std::promise<int> promise;	//声明一个std::promise对象,保存的值类型为int
	thread obj(MyThread, std::ref(promise), 10);
	obj.join();

	//获取结果值
	future<int> result = promise.get_future();
	thread obj1(MyThread1, std::ref(result));	//重新创建一个线程,将计算的结果给另外一个线程使用
	obj1.join();
	//auto value = result.get();	//get()只能调用一次

	//cout << "result = " << value << endl;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值