新闻中心

C++如何使用std::future和std::promise进行线程间通信?(代码示例)

2025-12-13
浏览次数:
返回列表
std::future和std::promise是C++11提供的单次值线程间传递机制:promise通过set_value/set_exception写入结果,future通过get/wait_for读取,共享状态自动同步,仅可移动不可拷贝。

c++如何使用std::future和std::promise进行线程间通信?(代码示例)

std::future 和 std::promise 是 C++11 引入的用于在线程间传递单次值的配套机制:promise 负责“设置”结果,future 负责“获取”结果。它们不共享内存,而是通过一个共享状态(shared state)解耦生产者与消费者,适合一对一线程通信或异步任务结果传递。

基本配对用法:一个线程设值,另一个取值

promise 对象持有可写入的共享状态,调用 set_value() 后,绑定的 future 就能通过 get() 安全读取(若未就绪则阻塞)。注意:每个 promise/future 对只能使用一次,且不能拷贝(仅可移动)。

// 示例:主线程等待子线程计算完成

#include <future>
#include <thread>
#include <iostream>

int main() {
    std::promise<int> prom;
    std::future<int> fut = prom.get_future(); // 获取关联的 future

    std::thread t([&prom]() {
        // 模拟耗时计算
        std::this_thread::sleep_for(std::chrono::seconds(1));
        prom.set_value(42); // 设置结果(只能调用一次)
    });

    std::cout << "等待结果...\n";
    int result = fut.get(); // 阻塞直到 set_value 被调用
    std::cout << "得到结果:" << result << "\n";

    t.join();
    return 0;
}

处理异常:用 set_exception 传递错误

如果异步操作可能失败,promise 支持通过 set_exception 传递异常对象,future 的 get() 会重新抛出该异常,避免错误被静默吞掉。

// 在子线程中捕获异常并转发

Mistral AI Mistral AI

Mistral AI被称为“欧洲版的OpenAI”,也是目前欧洲最强的 LLM 大模型平台

Mistral AI 182 查看详情 Mistral AI
std::thread t([&prom]() {
    try {
        throw std::runtime_error("计算失败");
    } catch (...) {
        prom.set_exception(std::current_exception()); // 转发当前异常
    }
});

try {
    int x = fut.get(); // 这里会抛出 runtime_error
} catch (const std::exception& e) {
    std::cout << "捕获异常:" << e.what() << "\n";
}

非阻塞检查:wait_for 与 wait_until

future 提供超时等待能力,避免无限阻塞。wait_for 返回 std::future_status 枚举值,可用于轮询或带超时的同步逻辑。

  • std::future_status::ready:值已就绪(set_value 或 set_exception 已调用)
  • std::future_status::timeout:超时,尚未就绪
  • std::future_status::deferred:仅适用于 std::async(launch::deferred),此处通常不出现
// 等待最多 500ms
if (fut.wait_for(std::chrono::milliseconds(500)) == std::future_status::ready) {
    std::cout << "成功获取:" << fut.get() << "\n";
} else {
    std::cout << "超时,任务未完成\n";
}

与 std::async 配合更简洁(但语义不同)

std::async 会自动创建 promise/future 对,并启动异步任务。它返回的 future 也支持 get()、wait_for 等操作,但底层调度由实现决定(可能延迟执行)。若需精确控制线程生命周期或手动触发,仍应显式使用 promise/future。

// 等效但更简短(内部仍用 promise/future 实现)
auto fut2 = std::async(std::launch::async, []() -> int {
    std::this_thread::sleep_for(std::chrono::seconds(1));
    return 123;
});
std::cout << "async 结果:" << fut2.get() <<; "\n";

基本上就这些。核心是理解 promise 是“写端”,future 是“读端”,共享状态自动管理线程安全——你不用加锁,get() 和 set_value() 内部已同步。注意别重复 set、别跨线程拷贝 promise/future、及时 join 或 detach 线程即可。

以上就是C++如何使用std::future和std::promise进行线程间通信?(代码示例)的详细内容,更多请关注其它相关文章!


# 最多  # 贵阳seo推广技巧报价  # 广告优化师网站有哪些  # seo创业论坛运营  # 专题网站如何建设和运用  # 昆明商城网站优化  # 泰州姜堰汽车网站建设  # 揭阳推广营销价格表最新  # 网站制作和推广文案范文  # 杭州网站推广乐云seo十年_  # 营销推广渠道是什么行业  # 相关文章  # 适用于  # ai  # 就能  # 边缘  # 抛出  # 尼克  # 欧洲  # 如何使用  # 游戏开发  # red  # 异步任务  # stream  # ios  # c++ 


相关栏目: 【 科技资讯46185 】 【 网络学院92790


相关推荐: QQ邮箱网页版入口 QQ邮箱官方邮箱登录通道  c++如何实现一个简单的软件渲染器_c++从零开始的3D图形学  在WordPress中通过REST API获取BasicAuth保护的远程文章  QQ邮箱在线登录平台 QQ邮箱个人邮箱网页版入口  Spring Boot嵌入式服务器与J*a EE:功能支持深度解析  天眼查怎么看公司融资情况 天眼查企业融资历史查询步骤【攻略】  C++ string find函数返回值npos详解_C++字符串查找失败的判断条件  ACG动漫手机版官网入口 手机ACG动漫APP在线观看正版  J*aScript中管理异步API调用:确保操作顺序与数据一致性  TikTok国际版官网直达_TikTok国际版官网直达进入在线观看  漫蛙官网正版漫画入口 漫蛙2官方网页登录地址  如何使用纯J*aScript判断Input元素是否在特定类容器内  谷歌浏览器浏览体验优化_谷歌浏览器新版直连永久可用提示  新三国志曹操传110级星符试炼夏侯渊极难攻略  在Blazor WebAssembly应用中动态注入客户端特定指标代码的策略  护手霜蹭到袖口上了如何清洗? 怎样避免留下一圈油印?  MAC如何将整个网页截长图_MAC使用Safari的导出为PDF或第三方工具  必由学网页版入口 必由学官方平台直接访问  谷歌浏览器怎么给标签页静音_Chrome标签静音快捷操作  在J*aScript中复现SciPy的B样条拟合与求值:关键考量  虫虫漫画精品漫画官网_虫虫漫画精品漫画官网进入精品漫画  Win11怎么关闭快速启动_Win11彻底关机设置教程  J*a里如何使用N*igableMap进行导航操作_可导航Map操作技巧解析  c++如何使用Meson构建系统_c++比CMake更快的构建工具  《铁拳8》黑皮辣妹新实机:元气满满的18岁少女!  没有大陆身份证/银行卡如何实名微信? 亲测有效的几种方法分享  不同用户不同价格! 索尼开启账户个性化定价测试  mcjs网页版流畅运行 mcjs低配电脑畅玩入口  Go RPC HTTP服务正确实现与常见陷阱解析  Win10双系统截图高效法 截屏快捷键速记【技巧】  J*aScript中赋值与自增运算符的复杂交互与执行机制  动漫花园资源网使用步骤_动漫花园资源网下载流程  Sublime Text怎么显示空格和制表符_Sublime显示不可见字符设置  css元素hover动画延迟生效怎么办_使用animation-delay调整触发时间  在J*a中如何在J*a中使用异常机制记录错误日志_异常日志实践经验  TikTok国际版网页端快速入口 TikTok全球版短视频浏览教程  汽水音乐在线版入口_汽水音乐网页播放手册  单12V-2&#215;6实现为RTX 5090供电750W!甚至都没敢跑分  Win11怎么查看电脑配置_Win11硬件配置检测工具使用  QQ邮箱官方邮箱登录入口 QQ邮箱网页版快速访问  如何使用Node.js csv 包按条件移除含空字段的CSV记录  Python getattr() 异常处理深度解析:避免程序意外退出  Yandex搜索引擎官网入口_俄罗斯Yandex免登录一键直达  妖精动漫免费平台 妖精动漫官网资源观看网址  PHP表单数据传递:如何通过隐藏输入字段获取动态ID  J*a如何使用AtomicInteger控制计数_J*a无锁计数器性能分析  j*a toString()的覆盖  QQ邮箱网页版快速登录 QQ邮箱邮箱账号官方入口地址  可靠CSGO开箱平台解析 CSGO开箱网合集  深入理解Go语言中Map值与方法接收器的交互:为什么需要临时变量 

搜索