1. 为什么需要异步线程池
在C++11之前,开发者需要手动管理线程的生命周期和同步机制,这不仅容易出错,还会导致性能瓶颈。想象一下餐厅里每位顾客都要求单独配一名厨师——资源很快就会被耗尽。C++11引入的异步操作和线程池就像开设了一家现代化餐厅:有固定数量的厨师(线程),通过任务队列(点餐系统)高效处理订单(任务)。
传统多线程开发面临三个主要痛点:
- 线程创建销毁开销大(相当于频繁雇佣和解雇临时工)
- 资源竞争导致性能下降(多个线程抢用同一个厨房设备)
- 同步逻辑复杂容易出错(协调不同厨师的工作顺序)
2. C++11异步操作核心组件
2.1 std::future与std::promise
这对黄金组合构成了C++异步编程的基础。std::promise是承诺提供结果的"生产者",std::future是等待获取结果的"消费者"。它们的协作流程就像外卖订单:
cpp复制std::promise<std::string> deliveryPromise; // 餐厅接单
auto customerReceipt = deliveryPromise.get_future(); // 顾客拿到取餐号
std::thread chef([&] {
std::this_thread::sleep_for(1s); // 模拟烹饪时间
deliveryPromise.set_value("Pizza"); // 出餐
});
std::cout << "Your order: " << customerReceipt.get(); // 顾客取餐
chef.join();
关键细节:
- get()是阻塞调用,会一直等待直到结果就绪
- 每个promise只能关联一个future
- 异常可以通过set_exception()传递
2.2 std::packaged_task
这个模板类将可调用对象包装成异步任务,就像把菜谱标准化:
cpp复制std::packaged_task<int(int,int)> recipe([](int a, int b) {
return a + b;
});
auto result = recipe.get_future();
