400 8949 560

NEWS/新闻

分享你我感悟

您当前位置> 主页 > 新闻 > 技术开发

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

发表时间:2026-01-02 00:00:00

文章作者:尼克

浏览次数:

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

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 值的最小可行代码:

#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() 会重新抛出

相关案例查看更多