并发,std::future和std::async

梦想游戏人
目录:
现代C++
当一个操作可以一步执行的时候,可以用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 来进一步封装任务,可以处理比如消息队列

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

Scroll Up