C++ 多线程异步(std::async)

本文介绍了C++11中的std::async函数,它能够异步调用函数并返回std::future对象。文章提供了两个示例,分别展示了std::launch::async和std::launch::deferred两种启动策略的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一 简介

C++11中的std::async是个模板函数。std::async异步调用函数,在某个时候以Args作为参数(可变长参数)调用Fn,无需等待函数执行完成就可返回,返回结果是个std::future对象。函数返回的值可通过std::future对象的get成员函数获取。一旦完成函数的执行,共享状态将包含函数返回的值并ready。

允许调用者选择特定的启动策略,第一个参数是std::async的启动策略类型是个枚举类enum class launch,包括:

  1. std::launch::async:异步,启动一个新的线程调用Fn,该函数由新线程异步调用,并且将其返回值与共享状态的访问点同步。

  2. std::launch::deferred:延迟,在访问共享状态时该函数才被调用。对Fn的调用将推迟到返回的std::future的共享状态被访问时(使用std::future的wait或get函数)。

参数Fn:可以为函数指针、成员指针、任何类型的可移动构造的函数对象(即类定义了operator()的对象)。Fn的返回值或异常存储在共享状态中以供异步的std::future对象检索。
参数Args:传递给Fn调用的参数,它们的类型应是可移动构造的。

二 例子

std::launch::async:异步

#include <iostream>
#include <string>
#include <chrono>
#include <thread>
#include <future>

using namespace std::chrono;
std::string getData()
 {
	//确保函数要5秒才能执行完成
	std::this_thread::sleep_for(seconds(5));
	return "Q是德华" ;
}

void breakCode() 
{
	//确保函数要5秒才能执行完成
	std::this_thread::sleep_for(seconds(5));
	return ;
}


int main() 
{
	//获取开始时间
	system_clock::time_point start = system_clock::now();

	std::future<std::string> strFuSec = std::async(std::launch::async, getData);
	breakCode();

	//数据在future<std::string>对象中可获取之前,将一直阻塞
	std::string strData = strFuSec.get();

	//获取结束时间
	auto end = system_clock::now();
	auto diff = duration_cast<std::chrono::seconds>(end - start).count();

	std::cout << "用时" << diff << "秒" << std::endl;
	std::cout << strData << std::endl;

	return 0;
}

结果
在这里插入图片描述
std::launch::deferred:延迟

#include <iostream>
#include <string>
#include <chrono>
#include <thread>
#include <future>

using namespace std::chrono;
std::string getData() 
{
	//确保函数要5秒才能执行完成
	std::this_thread::sleep_for(seconds(5));
	return "Q是德华" ;
}

void breakCode() 
{
	//确保函数要5秒才能执行完成
	std::this_thread::sleep_for(seconds(5));
	return ;
}


int main() 
{
	//获取开始时间
	system_clock::time_point start = system_clock::now();

	std::future<std::string> strFuSec = std::async(std::launch::deferred, getData);
	breakCode();

	//数据在future<std::string>对象中可获取之前,将一直阻塞
	std::string strData = strFuSec.get();

	//获取结束时间
	auto end = system_clock::now();
	auto diff = duration_cast<std::chrono::seconds>(end - start).count();

	std::cout << "用时" << diff << "秒" << std::endl;
	std::cout << strData << std::endl;

	return 0;
}

结果
在这里插入图片描述
第一个参数如果不写,自动选择,因此启动策略是不确定的,可能是std::launch::async,也可能是std::launch::deferred,或者是两者的任意组合,取决于它们的系统和特定库实现。vs是std::launch::deferred
lamda函数,第一个参数如果不写

#include <iostream>
#include <string>
#include <chrono>
#include <thread>
#include <future>

using namespace std::chrono;

int main() 
{
	//获取开始时间
	system_clock::time_point start = system_clock::now();

	std::future<std::string> strFuSec = std::async([]()->std::string {
		//确保函数要5秒才能执行完成
		std::this_thread::sleep_for(seconds(5));
		return "Q是德华";
	});

	[]() 
	{
		//确保函数要5秒才能执行完成
		std::this_thread::sleep_for(seconds(5));
		return;
	}();

	//数据在future<std::string>对象中可获取之前,将一直阻塞
	std::string strData = strFuSec.get();

	//获取结束时间
	auto end = system_clock::now();
	auto diff = duration_cast<std::chrono::seconds>(end - start).count();

	std::cout << "用时" << diff << "秒" << std::endl;
	std::cout << strData << std::endl;

	return 0;
}

结果
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值