在本站中
本站是开源的,仓库在 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) | 本卷 |
|---|---|---|
| mio | 1.2.1 | 1.2.4 |
| tokio | 1.52.3 | 1.54.1(tokio 卷) |
| mio 的 feature | os-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 的旧写法,那一节用同一个程序对比过两个版本,事件数相同。
两页:
- 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。 - 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"]