0

0

c++ std::future和std::promise c++线程间通信【教程】

尼克

尼克

发布时间:2026-01-02 00:33:15

|

104人浏览过

|

来源于php中文网

原创

std::future 和 std::promise 是 C++11 提供的线程安全异步值传递机制,用于单次结果传递;promise 设置值或异常(仅一次),future 通过 get() 获取(仅一次),二者通过共享状态关联,支持移动但不可拷贝。

c++ std::future和std::promise c++线程间通信【教程】

std::future 和 std::promise 是 C++11 引入的一对配套工具,用于在线程间安全地传递单次结果值,适合“一个线程生产、另一个线程消费”的场景。它们不共享内存,也不需要手动加锁,本质是基于同步通道的异步值传递机制。

std::promise 负责设置结果值

每个 std::promise 对象关联一个共享状态(shared state),它只能被调用一次 set_value()set_exception()set_exception_at_thread_exit()。多次调用会抛出 std::future_error 异常。

  • promise 必须在设置值前,把对应的 future 交给消费者线程(通常通过 move 语义转移)
  • promise 对象本身可被移动,但不可拷贝;它的 shared state 是线程安全的
  • 如果 promise 被销毁而未设置值,其 shared state 会以 std::future_error 异常结束

std::future 负责获取结果值

future 是 promise 的“读取端”,通过 get() 阻塞等待并取出值(或异常)。get() 只能调用一次,之后 future 失效(变为无效状态)。

  • 调用 get() 会阻塞当前线程,直到 promise 设置了值或异常
  • future 支持 wait()、wait_for()、wait_until() 等非阻塞等待方式,用于轮询或超时控制
  • future 也可由 std::async、std::packaged_task 自动创建,不一定非要配对使用 promise

典型协作流程示例

以下是一个跨线程传递 int 值的最小可行代码:

EduPro
EduPro

EduPro - 留学行业的AI工具箱

下载

立即学习C++免费学习笔记(深入)”;

#include 
#include 
#include 

int main() {
    std::promise p;
    std::future f = p.get_future(); // 获取关联 future

    std::thread t([&p]() {
        std::this_thread::sleep_for(std::chrono::seconds(1));
        p.set_value(42); // 生产者设值
    });

    std::cout << "等待中..." << std::endl;
    int result = f.get(); // 消费者取值(阻塞)
    std::cout << "得到:" << result << std::endl;

    t.join();
}

注意:lambda 捕获 promise 时需用引用(&p),否则 set_value 作用于副本,主线程将永远阻塞。

常见陷阱与建议

  • 避免复制 future 或 promise —— 它们都只支持移动语义
  • 不要在 promise 析构前忘记 set_value;可用 std::optional + RAII 封装规避
  • 若需多次通信,不要强行复用 future/promise;改用 std::queue + mutex 或 std::condition_variable
  • 异常传播很自然:promise.set_exception(std::make_exception_ptr(...)),future.get() 会重新抛出

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

312

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

522

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

49

2025.08.29

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

190

2025.08.29

lambda表达式
lambda表达式

Lambda表达式是一种匿名函数的简洁表示方式,它可以在需要函数作为参数的地方使用,并提供了一种更简洁、更灵活的编码方式,其语法为“lambda 参数列表: 表达式”,参数列表是函数的参数,可以包含一个或多个参数,用逗号分隔,表达式是函数的执行体,用于定义函数的具体操作。本专题为大家提供lambda表达式相关的文章、下载、课程内容,供大家免费下载体验。

202

2023.09.15

python lambda函数
python lambda函数

本专题整合了python lambda函数用法详解,阅读专题下面的文章了解更多详细内容。

187

2025.11.08

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

472

2023.08.10

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

472

2023.08.10

php源码安装教程大全
php源码安装教程大全

本专题整合了php源码安装教程,阅读专题下面的文章了解更多详细内容。

74

2025.12.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
React 教程
React 教程

共58课时 | 3.2万人学习

Pandas 教程
Pandas 教程

共15课时 | 0.9万人学习

ASP 教程
ASP 教程

共34课时 | 3万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号