Rust中与C++ std::promise和std::future的等价实现方案
Rust中与C++ std::promise和std::future的等价实现方案
嘿,我来给你唠唠Rust里怎么实现和C++的std::promise、std::future一模一样的同步功能,而且不用异步框架tokio,纯靠标准库就能搞定~
首先得明确,C++里std::promise是用来在一个线程里设置任务结果的,std::future则是让另一个线程(比如主线程)等待并获取这个结果。Rust标准库虽然没有直接叫这俩名字的同步工具,但有个超贴合的替代品——std::sync::mpsc::oneshot,也就是一次性通道,正好对应这种“一次发送、一次接收”的场景。
先给你补全完整的C++示例代码,方便对照理解:
#include <chrono> #include <future> #include <iostream> #include <thread> int main() { std::promise<int> prom; std::future<int> fut = prom.get_future(); // 子线程执行耗时任务后设置结果 std::thread t([&prom]() { std::this_thread::sleep_for(std::chrono::seconds(1)); prom.set_value(42); // 把任务结果42传给promise }); // 主线程阻塞等待future的结果 std::cout << "Waiting for result..." << std::endl; int result = fut.get(); std::cout << "Got result: " << result << std::endl; t.join(); return 0; }
下面是完全等价的Rust代码,用oneshot通道实现:
use std::sync::mpsc::oneshot; use std::thread; use std::time::Duration; fn main() { // 创建一次性通道:tx相当于C++的promise,rx相当于C++的future let (tx, rx) = oneshot::channel(); // 子线程执行任务,完成后发送结果 thread::spawn(move || { thread::sleep(Duration::from_secs(1)); // send方法对应C++的set_value,如果接收端已经销毁会panic,你也可以用send_ok优雅处理 tx.send(42).expect("Failed to send task result"); }); // 主线程阻塞等待接收结果,recv对应C++的future.get() println!("Waiting for result..."); let result = rx.recv().expect("Failed to receive task result"); println!("Got result: {}", result); }
如果需要模拟C++里promise.set_exception的异常传递功能,Rust里可以用Result类型来包装结果,把错误也一起传递:
use std::sync::mpsc::oneshot; use std::thread; use std::time::Duration; // 定义自定义错误类型 #[derive(Debug)] enum TaskError { CalculationFailure, Timeout, } fn main() { let (tx, rx) = oneshot::channel(); thread::spawn(move || { thread::sleep(Duration::from_secs(1)); // 模拟任务执行失败,发送错误 let task_result = Err(TaskError::CalculationFailure); tx.send(task_result).expect("Failed to send task result/error"); }); println!("Waiting for result..."); // 接收并处理结果或错误 match rx.recv() { Ok(Ok(val)) => println!("Task succeeded! Result: {}", val), Ok(Err(e)) => println!("Task failed with error: {:?}", e), Err(e) => println!("Receiver encountered an error: {}", e), } }
除了oneshot通道,如果你需要更灵活的同步控制(比如多次通知),也可以用std::sync::Mutex配合std::sync::Condvar来手动实现类似逻辑,但oneshot通道是最贴合C++ promise/future一次性语义的方案,代码也最简洁。
内容来源于stack exchange
相关产品推荐
相关产品推荐

