C++11 并发与多线程学习记录(八)

std::async、std::future

  • 启动一个异步任务(),返回一个std::future类模板对象,可以使用get函数获取结果。如果不需要返回值,可以使用std::future对象的wait函数。
    注意:有时候async并不创建线程,std::launch::async强制异步任务创建线程,std::launch::deferred并不创建线程,这是async于thread的最大不同。
  • get函数只能调用一次,且会一直阻塞到拿到返回值为止。
  • 给std::async传入std::launch类型参数,默认参数为std::launch::async|std::launch::deferred。std::launch::deferred可以延迟启动线程。直到调用wait或者get再启动,启动后没有创建新线程,而是直接在主线程中调用线程函数。
  • std::future还有其他的wait_for,wait_until函数。返回一个枚举类型std::future_status。
  • std::future可以使用valid()函数判断
  • std::launch::async|std::launch::deferred,参数表示async的行为从两者中选择,由系统自行选择。
int mythread(){
	std::chrono::milliseconds dura(5000);
	std::this_thread::sleep_for(dura);
	return 0;
}

int main()
{
	std::future<int> result = std::async(std::launch::async,mythread);
	std::future_status status = result.wait_for(std::chrono::seconds(6));
	if(status == std::future_status::ready)
	{
	    //线程执行完
		resutl.get();
	}
	else if(status == std::future_status::timeout)
	{
		//线程还没执行完,等待时间已经用完
	}
	else if(status == std::future_status::deferred)
	{
		//线程还没启动,此时传入的是std::launch::deferred
	}
	return 0;
}

std::shared_future

对于std::future,get函数的设计是移动语义,只能get一次。再次调用会报异常。
std::shared_future也是一个类模板。get函数复制结果。多个线程都可以get。

std::shared_future对象的使用

std::future result = std::async...
std::shared_future shared_result(std::move(result));
std::shared_future shared_result(result.share());//执行完毕,result空了

也可以直接使用get_future返回值强行转换。

std::packaged_task

类模板,模板参数是各种可调用对象。通过packaged_task包装成线程入口函数。所以packaged_task也是一个可调用对象。

std::string getDataFromDB(std::string token) {
  //获取数据
  std::string data = "Data fetched from DB by Filter :: " + token;
  return data;
}
 
int main() {
  //创建封装回调函数的packaged_task<>
  std::packaged_task<std::string(std::string)> task(getDataFromDB);
  //从packaged_task<>获取相关的future<>
  std::future<std::string> result = task.get_future();
  //将packaged_task传递给线程以异步运行
  std::thread th(std::move(task), "Arg");
  //join线程,阻塞直到线程完成时返回
  th.join();
  //获取packaged_task<>的结果,即getDataFromDB()的返回值
  std::string data = result.get();
  std::cout << data << std::endl;
 
  return 0;
}

std::promise

在一个线程中赋值,在另一个线程中取出来。
总结:通过promise保存一个值,在将来某个时刻把future绑定到promise上来得到绑定的值。可以将获取的future传入到其他线程,再调用get。

void mythread(std::promise<int > &tmpp, int data)
{
    //todo
	data++;	
	tmpp.set_value(data);
	
}

int main()
{
	std::promise<int > myprom;
	std::thread t1(mythread,std::ref(myprom),180);
	t1.join();
	
	//promise和future绑定,用于获取返回值
	std::future<int> fur = myprom.get_future();
	auto result = fur.get();
	
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值