Item35:优先考虑基于任务的编程而非基于线程的编程
大约 2 分钟
Item35:优先考虑基于任务的编程而非基于线程的编程
通常我们想执行一个异步任务的时候,通常会采用线程的方法。本节介绍了一种新的方法,即std::async
。其和std::thread
有很大的相似性。
std::async
的一个调用的例子如下所示:
auto fut = std::async(doAsyncWork); //"fut"表示"future"
从调用的形式可以看出,std::async会返回一个std::future
对象,这将让我们很方便的线程获取返回值。
因为线程存在处理线程耗尽、资源超额、负责均衡问题,如果我们使用std::thread
,就需要自己处理上述问题。但是std::async
则会帮助我们处理这些问题。
上述便是两点std::async
的优势。本节是建议大家在解决问题时,可以优先考虑std::async
,因为其简单易用。 但是这不意味着不使用std::thread
。
在下面的场景中,std::thread
更具有优势:
- 你需要访问非常基础的线程API。C++并发API通常是通过操作系统提供的系统级API(pthreads或者Windows threads)来实现的,系统级API通常会提供更加灵活的操作方式(举个例子,C++没有线程优先级和亲和性的概念)。为了提供对底层系统级线程API的访问,std::thread对象提供了native_handle的成员函数,而std::future(即std::async返回的东西)没有这种能力。
- 你需要且能够优化应用的线程使用。举个例子,你要开发一款已知执行概况的服务器软件,部署在有固定硬件特性的机器上,作为唯一的关键进程。
- 你需要实现C++并发API之外的线程技术,比如,C++实现中未支持的平台的线程池。
总结
- std::thread API不能直接访问异步执行的结果,如果执行函数有异常抛出,代码会终止执行。
- 基于线程的编程方式需要手动的线程耗尽、资源超额、负责均衡、平台适配性管理。
- 通过带有默认启动策略的std::async进行基于任务的编程方式会解决大部分问题。
Loading...