1、第三届中国Rust开发者会Rust 是否需要另种“彩”的 Future?郭兴,字节跳动服务框架团队研发程师。作者Rust 是否需要另种“彩”的 Future?标题Rust 编译器将 async 块翻译成由标准库提供的 Future 类型,户可以便地通过定义 Future 以实现阻塞的 IO 或并发控制语义。异步执器被允许在任意时刻删除成的 Future 实例以取消正在执的异步操作,但取消总是副作的吗?Rust 是否需要另种“颜”的 Future 为有副作取消的异步为提供安全保证?回顾如何使 Future 持基于 poll 的 IO,以及基于取消 Future 的流程控制#基于 Poll 的 F
2、utureio-uring 等异步模型让 Future 的取消不再副作,这可能导致严重的错误#不再是副作的取消#最终与折中案引另种“颜”的 Future 以最终解决问题,或者基于字节跳动开源的异步驱动器 monoio 探索的折中案录Rust 中的异步Rust 基于 Future trait 实现异步编程pub trait Future type Output;fn poll(self:Pin,cx:&mut Context)?Poll;pub trait Future type Output;fn poll(self:Pin,cx:&mut Context)?Poll;pub struct T
3、cpReadFuture io:TcpStream,buf:&buf mut u8,impl Future for TcpReadFuture type Output=io?Result;fn poll(self:Pin,_cx:&mut Context)?Poll let this=self.get_mut();match this.io.read(this.buf)Ok(n)?Poll?Ready(Ok(n),Err(ref e)if e.kind()?std?io?ErrorKind?WouldBlock?register poll event here Poll?Pending Err
4、(e)?Poll?Ready(Err(e),Future 中的 IO基于 poll 的 IO 事件被表达为在内核通知消息准备好时,次性地同步获取。struct PollOnce inner:F,impl Future for PollOnce where F:Future+Unpin,type Output=Option;fn poll(self:Pin,cx:&mut Context)?Poll let this=self.get_mut();match Pin?new(&mut this.inner).poll(cx)Poll?Ready(ready)?Poll?Ready(Some(re
5、ady),Poll?Pending?Poll?Ready(None),取消 Future户可以突破 async/await 封装的 Future 类型,被构造的 Future 类型不要求返回完成即可被析构。async fn task_one()/?/async fn task_two()/?/async fn race_tasks()let t1=task_one();let t2=task_two();pin!(t1,t2);select!()=t1?println!(task one completed first),()=t2?println!(task two completed fi
6、rst),Select:基于取消的并发控制语义select!是常的并发控制语义,它的语义当其中个分完成时即返回,不必等待所有 Future 实例完成。async fn listen(listener:TcpListener)loop let t1=listner.accept();let t2=timeout_2s();pin!(t1,t2);select!stream=t1?handle(stream).await,()=t2?println!(time out),取消不再是副作的取消基于完成的 IO 事件不再是副作的,基于副作取消的控制流程可能会引发致命错误。1.获取连结;2.进接收循环;