Rust in Everything
基于 mio 1.2.4

在本站中

本站是开源的,仓库在 yuxuetr/rustineverything。这一部分的站点链接都指向提交 89a61b1(2026-10-23),行号以它为准。

本站的代码里没有一行 mio::。Cargo.toml 第 46 行只写了 tokio:

tokio = { version = "1.49.0", features = ["full"] }

Cargo.lock 第 4489 行锁的是 mio 1.2.1,第 7938 行锁的是 tokio 1.52.3。谁把 mio 带进来、开了哪些 feature,用 cargo tree 反查(在站点仓库里跑,--offline --locked 保证不联网、不改 Cargo.lock;这时工作区的 Cargo.toml 和 Cargo.lock 与 89a61b1 相同):

cargo tree -f '{p} [{f}]' -i mio --offline --locked --depth 1 --color never
mio v1.2.1 [net,os-ext,os-poll]
└── tokio v1.52.3 [bytes,default,fs,full,io-std,io-util,libc,macros,mio,net,parking_lot,process,rt,rt-multi-thread,signal,signal-hook-registry,socket2,sync,time,tokio-macros]
    [dev-dependencies]

加上 --target x86_64-unknown-linux-gnu 或 --target aarch64-unknown-linux-gnu 结果相同。唯一的依赖方是 tokio。mio 的三个 feature 来自 tokio 1.52.3 的 Cargo.toml:net、process、signal 各自打开 mio/os-poll、mio/os-ext、mio/net;mio 自己的默认 feature log 没开,因为 tokio 写的是 default-features = false,所以 Cargo.lock 里 mio 的依赖只有 libc、wasi、windows-sys。三个 feature 各管什么,见源码地图。

项本站(89a61b1)本卷
mio1.2.11.2.4
tokio1.52.31.54.1(tokio 卷)
mio 的 featureos-poll、os-ext、net实验同样开这三个
生产Linux,epoll,docker 里跑 dx bundle --release 的产物—
开发macOS,kqueue,dx serve 的 debug 构建—

mio 1.2.1 到 1.2.4 的 20 个改了 src/ 的提交,已经在怎么读这一卷的「1.2.1 到 1.2.4」一节逐个对过:Linux 上没有一个提交改变行为;macOS 上换了实现的只有 Waker(#1987、#1988:不再在创建时 setup,wake 改用 EV_ADD | EV_ONESHOT),另有 #2016 改了 kqueue Event 的 Debug 输出。本站生产跑在 Linux 上,所以本卷读的 1.2.4 和生产用的 1.2.1 在生产上走的是同一份代码;开发机上 tokio 的唤醒走的是 1.2.1 的旧写法,那一节用同一个程序对比过两个版本,事件数相同。

两页:

  1. tokio 的 I/O 驱动怎么调 mio:tokio 1.52.3 在 Driver::new 里调 Poll::new、Waker::new(Token(0))、Registry::try_clone,每个 socket 用 ScheduledIo 的地址当 token、以 READABLE | WRITABLE 注册一次,turn() 每次用 1024 容量的 Events 调一次 poll,drop 时先 deregister 再关 fd。一个 echo 连接在 strace 里是 1 次 accept4、2 次 epoll_ctl、约 3 次 epoll_pwait;tokio 1.54.1 对 accept 出来的流先假定就绪,省掉第一次读之前的那次 epoll_pwait。
  2. Linux 与 macOS:生产和开发的差别:本卷里实测过的平台差别逐条对照 tokio 1.52.3 的源码,看哪些被 tokio 挡住、哪些没有。挡住的:一次 poll 的事件数、UDP 只报错误、peer_addr 的错误、Waker 的两个坑、drop 前注销。没挡住、但本站走不到的:max_io_events_per_tick(0)、AsyncFd 重复注册、kqueue 注册只生效一半时的 use-after-free。另有一条只在开发机上存在:debug 构建里 mio 的两道检查。
flowchart TB
  site["本站代码"] --> dioxus["dioxus-server 0.7.9"]
  dioxus --> lis["tokio TcpListener"]
  lis --> tokio["tokio 1.52.3 驱动"]
  tokio --> mio["mio 1.2.1"]
  mio -->|生产 Linux| epoll["epoll"]
  mio -->|开发 macOS| kq["kqueue"]

💬 关联讨论

发起讨论
加载中...