#io-uring #linux #非阻塞 #I/O #异步 #Linux 内核

uringy

基于 io_uring 的简单单线程并发运行时,适用于 Rust

2 个不稳定版本

0.5.0 2023 年 8 月 30 日
0.4.0 2022 年 7 月 26 日
0.3.0 2022 年 4 月 29 日
0.2.0 2022 年 4 月 29 日
0.1.2 2021 年 11 月 16 日

#647异步

每月 24 次下载

MIT 许可证

57KB
1K SLoC

Uringy

website github crates-io docs-rs license

Rust 中编写并发代码不必痛苦。Uringy 是一个运行时,它结合了结构化并发、单线程设计和 Linux 的 io_uring。适用于服务器应用程序,从简单的单线程到高度可扩展的线程每核心设计。

目标

简单的 API

  • 熟悉的阻塞语法,与 Rust 的标准库紧密对应
  • 避免 async/await 的限制和陷阱
  • 具有出色的文档和示例,易于学习
  • 使用非 Send 和非 'static 类型启动
  • 具有一流取消支持的纤维层次结构,无泄漏

性能优良

  • 使用 io_uring 发送非阻塞、批量、零拷贝系统调用
  • 使用协作多任务进行高效上下文切换
  • 无原子调度器,如有需要可手动并行化

编译速度快

  • 使用 [cargo 特性](#编译时间标志) 仅编译所需内容
  • 依赖性最小化
  • 宏使用最少

快速入门

安装 Rust创建新的 cargo 项目

将 uringy 添加为依赖项:cargo add uringy

然后替换 src/main.rs

// No need for async main
#[uringy::start]
fn main() {
    let handle = uringy::fiber::spawn(|| tcp_echo_server(9000)); // No need for async block

    uringy::signals().filter(Signal::is_terminal).next().unwrap();
    uringy::println!("gracefully shutting down");
    handle.cancel(); // Cancellation propagates throughout the entire fiber hierarchy

    // Automatically waits for all fibers to complete
}

// No need for async functions
fn tcp_echo_server(port: u16) {
    let listener = uringy::net::TcpListener::bind(("0.0.0.0", port)).unwrap();
    uringy::println!("listening for TCP connections on port {port}"); // No need for .await
    let mut connections = listener.incoming();
    while let Ok((stream, _)) = connections.next() {
        uringy::fiber::spawn(move || handle_connection(stream));
    }
}

fn handle_connection(tcp: TcpStream) {
    let (mut r, mut w) = stream.split();
    let _ = std::io::copy(&mut r, &mut w); // TcpStream implements std::io's Read and Write
}

然后使用:cargo run --release 运行您的项目

如果您使用的是 macOS,请使用一个 Linux 虚拟机 或 docker 容器。如果您使用的是 Windows,请使用 WSL

有关更多信息,请查看 示例目录

编译时间标志

目前没有 cargo 标志。

与其他运行时的比较

std 线程 uringy 纤维 tokio 任务
操作系统支持 全部 Linux 大多数
IO接口 阻塞 io_uring epoll + 线程池
功能颜色 同步 同步 同步和异步
启动 不适用 27 μs 27.5 μs (使用当前线程调度器,3.5 μs)
spawn 9828 ns 59 ns 907 ns (使用当前线程调度器,58ns)
spawn Send 绑定 是,除非使用LocalSet
spawn 'static 绑定 是,除非使用作用域 是,除非使用作用域
栈大小 虚拟8MB(可配置),4KB增量 虚拟128KB(可配置),4KB增量 完美大小
栈限制 可能溢出 可能溢出 不能使用递归
上下文切换 1405 ns 60 ns 1328 ns (使用当前线程调度器,308 ns)
多任务 抢占式 合作式 主要是合作式
结构化并发 无保证 父纤维比其子纤维寿命长 无保证
运行到 主线程完成 所有纤维完成 block_on 完成
并行 自动 手动 自动,除非使用当前线程调度器
用户空间调度器 不适用 最小化 工作窃取
取消 使用异端Unix信号 一等,自愿 泄漏内存,导致错误

支持的Rust版本

MSRV是1.70.0(于2023年6月发布)。请在终端中运行rustc --version来检查您的Rust版本。

支持的Linux内核版本

最低内核版本是6.1(于2022年12月发布)。请在终端中运行uname -r来检查您的内核版本。

许可

Uringy遵循MIT许可。这是一个宽容的许可,基本上意味着你可以做任何你想做的事情。

依赖

~370–560KB
~13K SLoC