讲座主题:C++中的std::shared_future
与std::future
:一场关于共享与独占的对话
开场白:你好,未来的朋友们!
欢迎来到今天的C++技术讲座!今天我们要聊一聊两个非常有趣的家伙——std::future
和std::shared_future
。它们就像一对性格迥异的兄弟,一个喜欢独占资源,另一个却愿意分享。那么,到底谁更适合你的代码呢?让我们一起揭开它们的神秘面纱吧!
第一部分:std::future
登场——独占资源的小霸王
std::future
是C++标准库中用于处理异步任务结果的对象。它就像是一个快递员,负责把异步任务的结果送到你手中。但请注意,这个快递员有点“傲娇”——它只允许一个人接收包裹。
核心特点:
- 独占性:每个
std::future
对象只能被一个线程调用其get()
方法来获取结果。 - 一次性消费:一旦调用了
get()
,结果就被消费掉了,不能再被其他std::future
对象访问。 - 简单直接:适合单线程或简单的异步场景。
示例代码:
#include <iostream>
#include <future>
#include <thread>
int main() {
std::packaged_task<int()> task([]{ return 42; });
std::future<int> future = task.get_future();
std::thread t(std::move(task));
t.join();
// 只能调用一次 get()
std::cout << "Result: " << future.get() << std::endl;
return 0;
}
总结:
std::future
是一个很好的工具,但它有一个局限性:如果你有多个线程需要访问同一个异步任务的结果,std::future
就显得力不从心了。这时,就需要请出它的兄弟——std::shared_future
。
第二部分:std::shared_future
上场——乐于分享的好邻居
std::shared_future
是std::future
的升级版,它解决了std::future
无法共享结果的问题。你可以把它想象成一个共享快递柜,多个线程都可以从中取包裹。
核心特点:
- 可共享性:多个
std::shared_future
对象可以共享同一个异步任务的结果。 - 多次消费:每个
std::shared_future
对象都可以独立调用get()
,获取相同的结果。 - 灵活性:适合多线程环境下的复杂异步场景。
示例代码:
#include <iostream>
#include <future>
#include <thread>
#include <vector>
void print_result(const std::shared_future<int>& sf) {
std::cout << "Thread " << std::this_thread::get_id()
<< " got result: " << sf.get() << std::endl;
}
int main() {
std::promise<int> promise;
std::shared_future<int> shared_future = promise.get_future();
std::vector<std::thread> threads;
for (int i = 0; i < 5; ++i) {
threads.emplace_back(print_result, shared_future);
}
promise.set_value(42);
for (auto& t : threads) {
t.join();
}
return 0;
}
表格对比:
特性 | std::future |
std::shared_future |
---|---|---|
是否可共享 | 否 | 是 |
调用get() 次数 |
仅一次 | 多次 |
使用场景 | 单线程或简单异步场景 | 多线程或多消费者场景 |
第三部分:选择的艺术——什么时候用哪个?
现在我们知道了std::future
和std::shared_future
的区别,但如何选择合适的工具呢?以下是一些实用建议:
- 单线程场景:如果你只需要在一个线程中获取异步任务的结果,
std::future
足够了。 - 多线程场景:如果你有多个线程需要访问同一个异步任务的结果,使用
std::shared_future
。 - 性能考虑:
std::shared_future
会带来一些额外的开销(例如引用计数管理),因此在性能敏感的场景下要权衡利弊。
官方文档引用:
根据C++标准文档(ISO/IEC 14882),std::shared_future
的设计初衷是为了支持多消费者模式,而std::future
则更注重简单性和效率。
第四部分:总结与展望
通过今天的讲座,我们了解了std::future
和std::shared_future
的基本概念、区别以及适用场景。它们就像是C++并发世界的两把利器,各有千秋。记住,选择合适的工具才是解决问题的关键。
最后,送给大家一句话:编程就像做饭,选对食材才能做出美味佳肴!希望今天的讲座能帮助大家更好地理解C++的并发工具。下次见啦,祝大家编码愉快!