何时需使用std::shared_future而非std::future实现线程同步?
先澄清你测试代码里的关键问题:当你把sf改成普通std::future并通过引用让两个线程共享时,这种行为是未定义的——你当前运行正常只是运气好,C++标准并不保证多个线程并发访问同一个std::future对象的wait()是安全的,换个编译器、平台或者多次运行都可能出现死锁、崩溃等异常。
std::future与std::shared_future的核心区别
- 所有权模型:
std::future是独占式的:一个future对象独占异步结果的状态,它不可拷贝,只能移动。一旦调用get(),结果的所有权就会被转移,future对象会进入无效状态,无法再使用。std::shared_future是共享式的:可以被自由拷贝,多个shared_future对象共享同一个异步状态。所有对象都能独立调用wait()或get(),不会互相影响。
- 线程安全性:
std::future的成员函数(除了移动操作)没有被规定为线程安全,并发访问同一个future对象属于未定义行为。std::shared_future的所有成员函数都是线程安全的,多个线程可以同时调用wait()、get()等操作,无需额外同步。
- 结果获取:
std::future::get()只能调用一次,调用后对象失效。std::shared_future::get()可以调用多次,且是const成员函数,多个线程调用都能获取到结果的副本(如果是值类型)或引用(如果是引用类型的future)。
必须使用std::shared_future的场景
- 多个线程需要获取同一个异步结果:比如一个异步任务计算出一份配置数据,多个工作线程都需要读取这份数据。用
shared_future可以让每个线程都调用get()获取完整结果,而future只能被一个线程获取一次,之后就无法再用。 - 多个线程需要等待同一个异步事件完成:比如多个线程需要等待某个初始化任务完成后再继续执行,用
shared_future的wait()可以安全地实现这种同步,而用future的话,并发调用wait()是未定义行为。 - 需要将异步状态传递给多个线程:由于
std::future不可拷贝,只能移动,无法同时传递给多个线程。而std::shared_future可以拷贝,每个线程持有自己的shared_future对象,共享同一个异步状态。
关于“是否是std::future的简单包装”
它和std::shared_ptr的设计思路类似——通过共享所有权实现多对象访问同一资源,但std::shared_future不是简单的包装:它专门针对异步状态的共享访问做了线程安全设计,确保多个线程的并发操作不会破坏状态的一致性,这是std::future做不到的。
内容的提问来源于stack exchange,提问作者gongliming7
相关产品推荐
相关产品推荐

