---
title: tokio 运行时
url: https://doc.liz6.com/rust/06-concurrency-and-asynchrony/03-tokio-runtime
locale: zh
area: rust
tags:
- rust
- 并发与异步
date: 2026-06-30
modified: 2026-06-30
description: tokio 的 reactor(基于 epoll/kqueue/IOCP)负责异步 IO,executor 用 work-stealing 调度 Future 到多线程——两者合起来是 Rust 异步的事实标准运行时。spawn 把 Future 提交到线程池,select! 同时等待多个异步操作——理解 react…
---

# tokio 运行时

> tokio 的 reactor(基于 epoll/kqueue/IOCP)负责异步 IO,executor 用 work-stealing 调度 Future 到多线程——两者合起来是 Rust 异步的事实标准运行时。`spawn` 把 Future 提交到线程池,`select!` 同时等待多个异步操作——理解 reactor 和 executor 的分工就理解了 tokio 的性能模型。

## tokio 的三层架构

```mermaid
flowchart TD
    TASK["🧵 你的 async task<br/>tokio::spawn"]

    TASK --> QUEUE["📋 Task Queue<br/>等待调度的 Future"]

    QUEUE --> EXECUTOR["⚙️ Executor<br/>work-stealing scheduler<br/>一个 CPU 核心一个 worker thread"]

    EXECUTOR --> REACTOR["🔌 Reactor<br/>epoll (Linux) / kqueue (macOS)<br/>IOCP (Windows)"]

    REACTOR --> KERNEL["🐧 OS Kernel"]

    REACTOR -.->|"IO 就绪 → 唤醒 task"| QUEUE

    classDef user fill:#e3f2fd,stroke:#1565c0
    classDef middle fill:#fff3e0,stroke:#ef6c00
    classDef os fill:#f3e5f5,stroke:#7b1fa2
    class TASK,QUEUE user
    class EXECUTOR,REACTOR middle
    class KERNEL os
```

**Reactor**：监听所有注册的 IO 源（socket, timer, signal）→ IO 就绪 → 通知对应的 task 被唤醒。
**Executor**：维护 task queue → 被唤醒的 task 重新获得 CPU time。
**你的代码**：值调用 async fn 和 `.await`，不直接与 reactor 或 executor 打交道。

## 两种 runtime

```rust
// 多线程 (默认)
#[tokio::main]
async fn main() { ... }

// 等价于:
fn main() {
    tokio::runtime::Builder::new_multi_thread()
        .worker_threads(num_cpus::get())  // 默认: CPU 核数
        .enable_all()                     // IO + 时间
        .build().unwrap()
        .block_on(async { ... });
}

// 单线程 (用于简单场景, 如不需要跨线程同步)
#[tokio::main(flavor = "current_thread")]
async fn main() { ... }
```

## spawn: 独立的并发 task

```rust
let handle = tokio::spawn(async move {
    let result = do_heavy_work().await;
    println!("{}", result);
});
// handle: JoinHandle — 可以 .await 获取返回值
let result = handle.await.unwrap();
```

spawn 的 task 可以在不同的 worker thread 上执行——它是真正的并发，不是协程。返回的 `JoinHandle` 是一个 Future，`.await` 它等待 task 完成。

## Work Stealing Scheduler

每个 worker thread 有自己的 local task queue。当某个 worker idle 时，随机偷其他 worker 的 task。这比"一个全局 queue + 所有 worker 竞争"的模型更高效——减少了锁竞争，因为 local push/pop 是无锁的。

## select!: 等待多个 Future

```rust
tokio::select! {
    result = long_running_op() => { /* 处理结果 */ }
    _ = tokio::signal::ctrl_c() => { /* Ctrl+C 信号 */ }
}
```

任何一个 branch 完成 → 其他 branches 被**取消**（drop）。这是 async Rust 内置的取消模型——不需要显式的 cancellation token。被取消的 Future 的 Drop 实现负责清理资源。

## 参考

- **tokio**: docs.rs/tokio, tokio.rs
- **async book**: rust-lang.github.io/async-book

*Keywords: tokio, reactor, executor, work stealing, spawn, select!, runtime, current_thread*
