面试题答案
一键面试Future trait 和 Poll 机制的协同工作
- Future trait:在 Rust 异步编程中,
Future
是一个 trait,代表一个可能尚未完成的计算。它定义了一个poll
方法,用于检查 Future 是否完成。一个实现了Future
trait 的类型,表示这个类型代表的任务是异步可执行的。 - Poll 机制:
Poll
是一个枚举,定义在std::task::Poll
中,有两个变体:Poll::Ready(T)
和Poll::Pending
。poll
方法返回Poll
类型的值,Poll::Ready(T)
表示异步任务已经完成,并返回结果T
;Poll::Pending
表示任务尚未完成,需要再次轮询。
Future
trait 的 poll
方法由执行器(executor)调用。执行器负责调度和运行 Future。当执行器调用 Future
的 poll
方法时,poll
方法检查任务的状态,如果任务已完成,返回 Poll::Ready(T)
;如果任务未完成,返回 Poll::Pending
,执行器会在适当的时候(例如等待的 I/O 操作完成时)再次调用 poll
方法。
手动实现一个简单的 Future 及使用 Poll 控制状态
use std::future::Future;
use std::task::{Context, Poll};
// 定义一个简单的 Future 结构体
struct MyFuture {
state: i32,
}
impl Future for MyFuture {
type Output = i32;
fn poll(self: std::pin::Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
if self.state < 10 {
self.state += 1;
// 任务未完成,返回 Poll::Pending
Poll::Pending
} else {
// 任务完成,返回 Poll::Ready 及结果
Poll::Ready(self.state)
}
}
}
fn main() {
let mut future = MyFuture { state: 0 };
loop {
let poll_result = future.as_mut().poll(&mut Context::from_waker(&std::task::noop_waker()));
match poll_result {
Poll::Pending => {
println!("Task is pending, continue polling...");
}
Poll::Ready(result) => {
println!("Task is ready with result: {}", result);
break;
}
}
}
}
在上述代码中:
- 定义了
MyFuture
结构体,它包含一个state
字段用于表示任务的状态。 - 为
MyFuture
实现Future
trait,Output
类型为i32
。 - 在
poll
方法中,根据state
的值判断任务是否完成。如果state
小于10
,任务未完成,返回Poll::Pending
并增加state
的值;当state
达到或超过10
时,任务完成,返回Poll::Ready(self.state)
。 - 在
main
函数中,通过一个循环手动调用poll
方法来模拟执行器的调度,直到任务完成。