async,future,packaged_task,promise

一、std::async,std::future
创建后台任务并返回值希望线程返回一个结果
std::async是个函数模板,用来启动一个异步任务,启动起来返回std::future创建一个线程并开始执行对应的线程函数返回std::future
std::future对象里面就有线程函数的返回结果,可能没办法马上得到,
但是在线程执行完毕的时候,就会返回结果了

#include<future>
using namespace std;

int mythread()
{
	cout << "mythread() start. thread id =" << std::this_thread::get_id() << endl;
	std::this_thread::sleep_for(2s);//休息2秒
	cout << "mythread() end. thread id =" << std::this_thread::get_id() << endl;
	return 5;
}

int main()
{
	cout << "main id = " << std::this_thread::get_id() << endl;
	std::future<int> result = std::async(mythread);
	cout << "continue.... " << endl;
	cout << result.get() << endl;//只能调用一次,调用多次报异常

}

可以通过额外向std::async()传递一个参数,该参数类型是std::launch类型(枚举类型),来达到一些特殊的目的。
比如std:launch::deferred:表示线程入口函数调用被延迟到std::future的wait()或者get()函数调用时才执行
如果没调用get()或者wait(),那么线程根本就没有创建。
并且没有新线程的创建,是在主线程里执行的

class A {
public:
	int mythread(int mypar)
	{
		cout << mypar << endl;
		cout << "mythread() start. thread id =" << std::this_thread::get_id() << endl;
		std::this_thread::sleep_for(2s);//休息2秒
		cout << "mythread() end. thread id =" << std::this_thread::get_id() << endl;
		return 5;
	}
};


int main()
{
	A a;
	int tmpper = 12;
	cout << "main id = " << std::this_thread::get_id() << endl;
	std::future<int> result = std::async(std::launch::deferred,&A::mythread,&a,tmpper);//第二个是引用保证是原对象
	cout << "continue.... " << endl;
	//cout << result.get() << endl;
}

在这里插入图片描述
在这里插入图片描述

std::launch::async

则是创建一个子线程,并且立即执行。
async()函数默认的就是async。

std::packaged_task:打包任务,把任务包装起来
是个类模板,模板参数是各种可调用对象。通过packaged_task来把各种可调用对象包装起来,方便将来作为线程入口函数用来调用

#include<future>
using namespace std;

int mythread(int mypar)
{
	cout << mypar << endl;
	cout << "mythread() start. thread id =" << std::this_thread::get_id() << endl;
	std::this_thread::sleep_for(2s);//休息2秒
	cout << "mythread() end. thread id =" << std::this_thread::get_id() << endl;
	return 5;
}

int main()
{
	cout << "main id = " << std::this_thread::get_id() << endl;
	std::packaged_task<int(int)> mypt(mythread);
	std::thread t1(std::ref(mypt),1);
	t1.join();
	std::future<int> result = mypt.get_future();
	cout << result.get() << endl;
	cout << "continue.... " << endl;

}
#include<future>
using namespace std;

int main()
{
	cout << "main id = " << std::this_thread::get_id() << endl;
	//packaged_task包装起来的可调用对象还可以直接调用,所以从这个角度来讲,packaged_task对象也是一个可调用对象
	std::packaged_task<int(int)> mypt([](int mypar) {
		cout << mypar << endl;
		cout << "mythread() start. thread id =" << std::this_thread::get_id() << endl;
		std::this_thread::sleep_for(2s);//休息2秒
		cout << "mythread() end. thread id =" << std::this_thread::get_id() << endl;
		return 5;
	});
	mypt(105);//相当于函数调用
	std::future<int> result = mypt.get_future();
	cout << result.get() << endl;
	cout << "continue.... " << endl;
	return 0;
}
vector<packaged_task<int(int)>> mytasks;
int main()
{
	cout << "main id = " << std::this_thread::get_id() << endl;
	//packaged_task包装起来的可调用对象还可以直接调用,所以从这个角度来讲,packaged_task对象也是一个可调用对象
	std::packaged_task<int(int)> mypt([](int mypar) {
		cout << mypar << endl;
		cout << "mythread() start. thread id =" << std::this_thread::get_id() << endl;
		std::this_thread::sleep_for(2s);//休息2秒
		cout << "mythread() end. thread id =" << std::this_thread::get_id() << endl;
		return 5;
	});
	mytasks.push_back(std::move(mypt));//入容器,mypt为空
	//...
	std::packaged_task<int(int)>mypt2;
	auto iter = mytasks.begin();
	mypt2 = std::move(*iter);
	mytasks.erase(iter);//删除第一个元素,迭代器失效
	mypt2(23);
	std::future<int> result = mypt2.get_future();
	cout << result.get() << endl;

	cout << "continue.... " << endl;
	return 0;
}
#include<future>
using namespace std;

//std::promise 类模板 
//能够在某个线程中给它赋值,然后在其他线程中把这个值取出来用。
//总结:通过promise保存一个值,在将来某个时刻我们通过一个future绑定到这个promise来获取这个绑定的值
void mythread(std::promise<int>&temp, int cal)
{
	cal++;
	this_thread::sleep_for(2s);
	int result = cal;//保存结果
	temp.set_value(result);//结果保存到temp对象中,
	return;
}

void mythread2(std::future<int> &temp)
{
	auto result = temp.get();
	cout << "mythread2 result " << result << endl;
}
int main()
{
	cout << "main id = " << std::this_thread::get_id() << endl;
	//packaged_task包装起来的可调用对象还可以直接调用,所以从这个角度来讲,packaged_task对象也是一个可调用对象
	std::promise<int>myprom;
	std::thread t(mythread, std::ref(myprom), 180);
	t.join();

	//获取结果值
	std::future<int> fu1 = myprom.get_future();//获取返回值

	std::thread t2(mythread2, std::ref(fu1));
	t2.join();

	cout << "continue.... " << endl;
	return 0;
}

猜你喜欢

转载自blog.csdn.net/a12345d132/article/details/84875457