当一个操作可以独立异步执行时,可以用 std::async 创建异步任务。异步任务的返回值就是任务函数的返回值,保存在 std::future(期望)中,需要结果时再通过 .get() 获取。注意 get 内部使用了 std::move。

int calculateBill(int base)
                {
                	Sleep(3000);
                	return base * 2;
                }
                
                int main(...)
                {
                	std::future<int> _ans = std::async(calculateBill, 100); //创建异步任务, 任务返回值保存在std::future中
                     //执行其他任务
                	cout << "1111" << endl;
                	cout << "222222" << endl;
                	Sleep(1);
                	cout << "3333333" << endl;
                	cout << "444444" << endl;
                
                   //需要异步任务结果的时候, 如果没返回 那么将会等待至返回
                	cout << _ans.get() << endl;//get操作会阻塞
                
                	while (true)
                	{
                		Sleep(100);
                	}
                
                	system("pause");
                	return 0;
                }

std::async 提供了 std::thread 所不具备的返回值功能。

异步启动策略

创建异步任务时还可以指定启动策略:

std::launch::async   //开一个新线程执行
                std::launch::deferred  //目标函数的调用延迟到wait或者get函数才执行 等同于 std::launch::sync
                std::launch::async | std::launch::deferred //等同于std::launch::any
                
                std::future<int> _ans = std::async( std::launch::async,calculateBill, 100); //异步执行
                std::future<int> _ans = std::async( std::launch::deferred,calculateBill, 100);//等到get 或者wait才执行

使用 std::packaged_task 封装任务

还可以用 std::packaged_task 来进一步封装任务,适合处理消息队列等场景。


                typedef std::packaged_task<int(int)> task;
                
                int calculateBill(int base)
                {
                	Sleep(500);
                	return base * 2;
                }
                
                int main(...)
                {
                	std::vector<task> tasks;
                
                
                	tasks.push_back(std::move(task(calculateBill)));
                	tasks.push_back(std::move(task(calculateBill)));
                	tasks.push_back(std::move(task(calculateBill)));
                	tasks.push_back(std::move(task(calculateBill)));
                	tasks.push_back(std::move(task(calculateBill)));
                	tasks.push_back(std::move(task(calculateBill)));
                	tasks.push_back(std::move(task(calculateBill)));
                	tasks.push_back(std::move(task(calculateBill)));
                	tasks.push_back(std::move(task(calculateBill)));
                	tasks.push_back(std::move(task(calculateBill)));
                
                
                
                	int i = 0;
                	for (auto & task : tasks)
                	{
                		task(++i);
                		std::future<int> ans1 = task.get_future();
                		cout << ans1.get() << endl;//阻塞会等待结果的返回
                	}
                
                	system("pause");
                	return 0;
                }
                
                

并发处理

也可以用多线程并发地执行任务队列:

	int i = 0;
                	for (auto & task : tasks)
                	{
                		std::thread t([&]
                		{
                			task(++i);
                			std::future<int> ans1 = task.get_future();
                			cout << ans1.get() << endl;
                		});
                
                		t.detach();
                	}

参考:https://github.com/progschj/ThreadPool