MST
星途 面试题库

面试题:Rust异步编程中的Future与Poll机制

请阐述在Rust异步编程中,Future trait和Poll机制是如何协同工作的。并举例说明如何手动实现一个简单的Future,包括如何使用Poll来控制异步任务的执行状态。
22.1万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试

Future trait 和 Poll 机制的协同工作

  1. Future trait:在 Rust 异步编程中,Future 是一个 trait,代表一个可能尚未完成的计算。它定义了一个 poll 方法,用于检查 Future 是否完成。一个实现了 Future trait 的类型,表示这个类型代表的任务是异步可执行的。
  2. Poll 机制Poll 是一个枚举,定义在 std::task::Poll 中,有两个变体:Poll::Ready(T)Poll::Pendingpoll 方法返回 Poll 类型的值,Poll::Ready(T) 表示异步任务已经完成,并返回结果 TPoll::Pending 表示任务尚未完成,需要再次轮询。

Future trait 的 poll 方法由执行器(executor)调用。执行器负责调度和运行 Future。当执行器调用 Futurepoll 方法时,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;
            }
        }
    }
}

在上述代码中:

  1. 定义了 MyFuture 结构体,它包含一个 state 字段用于表示任务的状态。
  2. MyFuture 实现 Future trait,Output 类型为 i32
  3. poll 方法中,根据 state 的值判断任务是否完成。如果 state 小于 10,任务未完成,返回 Poll::Pending 并增加 state 的值;当 state 达到或超过 10 时,任务完成,返回 Poll::Ready(self.state)
  4. main 函数中,通过一个循环手动调用 poll 方法来模拟执行器的调度,直到任务完成。