关于rust:DatenLord|iouring-Rust-异步库实现方法
简介io_uring 是 Linux 最新的异步 I/O 接口,采纳两个用户和内核共享的 ring buffer 进行交互,性能优于之前的接口且限度更少。尽管 io_uring 依然处于开发迭代中,然而根本的 I/O 接口曾经根本定型,作为高效零碎语言的 Rust 则成为应用该接口的不二之选。当初曾经有许多针对 io_uring 的 Rust 封装,然而有的存在soundness问题,有的存在性能问题,都不是平安高效 I/O 的好选项。咱们团队(DatenLord)也进行了本人的尝试,本文就是介绍咱们的 io_uring 异步库实现办法。 Rust 现有异步模式Rust 的异步库都有本人的异步 I/O 实现办法,然而外部原理大同小异,都是 Reactor 模式,如下图所示: Worker 线程将关注的 fd 注册到 Epoll 期待队列中,Reactor 线程通过 Epoll wait 期待能够进行操作的 fd,当有 fd 能够操作时,Reactor 线程告诉 Worker 线程进行真正的 I/O 操作。在此过程中,Reactor 线程仅仅起到期待和告诉的作用,并不真正进行 I/O 操作,并且这里的 I/O 接口依然是同步 I/O 接口。这种模式就好比请人帮忙烧开水,然而泡茶的过程还是本人亲自来。 Reactor 模式中,内存 buffer 始终在用户的管制下,在进行真正的 I/O 操作产生前,随时能够cancel正在期待的申请,因而Reactor 模式中不存在内存data race的状况,接口也就趁势应用了 reference,及借用机制。接口示例如下: fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> ImplFuture<'a, Result<usize>>io_uring Rust 底层封装io_uring 的官网库只有 C 语言版本及 liburing,因而 Rust 异步封装之前必须有一套可用的 Rust 底层封装。这一层封装大家有不同的抉择:有的抉择本人从头实现,如 tokio 的 io-uring;咱们的抉择则是复用 liburing,先进行一层binding,而后在进行一层面向对象的封装,形象出 SQ,CQ 和 Register 等,这一层形象借鉴的 tokio 的 io-uring。前一种办法对实现具备更强的控制力,后一种办法则升高了保护老本。无论哪一种办法,最终的目标和成果是一样的——搭建脚手架,为异步封装扫平阻碍。 ...