Rust in Everything
基于 tokio 1.54.1

任务

tokio::spawn 交出去的 future,在运行时里变成一个任务。源码在 runtime/task/,调度器只通过很窄的接口和它打交道:拿到一个 Notified 就调 run(),别的都由任务自己处理。

这一部分按任务的一生来读:

  1. 任务的内存布局:一次分配放下 Header、Core、Trailer;vtable 擦掉类型;Task、Notified、JoinHandle 是同一块内存的三个引用。
  2. 一个 usize 的状态机:6 个标志位加引用计数,所有状态转换都是一次 CAS。
  3. poll 与唤醒:Harness::poll 的四种结局;任务正在运行时被唤醒会怎样;panic 怎么被接住。
  4. JoinHandle、取消与 JoinError:怎么读到输出;abort 和任务完成赛跑时谁赢;drop JoinHandle 的快路径。
  5. OwnedTasks 与关闭:所有存活任务挂在分片链表上,运行时 drop 时逐个关掉。
flowchart TB
  spawn[spawn:分配 Cell] --> bind[OwnedTasks::bind]
  bind --> q[Notified 进队列]
  q --> poll[Harness::poll]
  poll -->|Pending| idle[空闲,等 wake]
  idle -->|wake| q
  poll -->|Ready / 取消 / panic| done[complete:写输出、叫醒 JoinHandle]
  done --> free[引用计数归零,释放]

读完这一部分,「04 调度器」里的队列、窃取和 LIFO 槽只需要关心一件事:手里的 Notified 交给谁去 run()。

💬 关联讨论

发起讨论
加载中...