21 个版本
0.2.0-alpha.1 | 2019 年 8 月 8 日 |
---|---|
0.1.18 | 2020 年 2 月 4 日 |
0.1.17 | 2019 年 12 月 4 日 |
0.1.16 | 2019 年 9 月 30 日 |
0.1.2 | 2018 年 3 月 30 日 |
27 在 #task-scheduler
135,626 每月下载量
在 少于 18 crates 中使用
570KB
10K SLoC
Tokio 线程池
一个库,用于在多个线程池中并发调度执行 future。
许可证
该项目受 MIT 许可证 的许可。
贡献
除非你明确说明,否则你提交的任何贡献,只要有意提交到 Tokio,都应按 MIT 许可,没有任何附加条款或条件。
lib.rs
:
用于执行 future 的工作窃取线程池。
Tokio 线程池支持在多个 CPU 核心上调度 future 并处理它们。它针对 Tokio 的主要用例进行了优化,即许多独立的任务,计算有限且大多数任务都在等待 I/O。通常,用户不会直接创建 ThreadPool
实例,而是通过 runtime
使用它。
ThreadPool
结构管理两套线程
- 工作线程。
- 备份线程。
工作线程用于使用工作窃取策略调度 future。另一方面,备份线程仅用于支持 blocking
API。线程将在这两套之间转换。
工作窃取策略的优点是最小化线程间的协调。线程池试图在不通过线程进行通信的情况下尽可能多地取得进展。
工作线程概述
每个工作线程有两个队列:一个双端队列和一个 mpsc 通道。双端队列是工作线程上安排运行的任务的默认队列。任务只能由工作线程推送到双端队列,但其他工作线程可以“窃取”该队列中的任务。mpsc 通道用于在池外部提交 future。
只要线程池没有被关闭,工作线程就会在一个循环中运行。每次循环,它都会消耗其mpsc通道上的所有任务,并将其推送到deque中。然后,它从deque中弹出任务并执行它们。
如果工作线程没有工作,即两个队列都为空。它会尝试窃取任务。为此,它会随机扫描其他工作线程的deque并尝试弹出任务。如果没有找到可窃取的工作,该线程将进入休眠状态。
当工作线程检测到池已关闭时,它会退出循环,清理其状态,并关闭线程。
线程池初始化
注意,用户通常将使用由 runtime
创建的线程池。
默认情况下,在创建时不会生成任何线程。相反,当新的futures生成时,池首先检查是否有足够的活跃工作线程。如果没有,将生成一个新的工作线程。
生成futures
生成行为取决于futures是在工作线程或线程内部生成,还是从外部句柄生成。
当在外部线程池中生成futures时,当前策略是随机选择一个工作线程来提交任务。然后,将任务推送到该工作线程的mpsc通道。
当在工作线程上生成futures时,任务将被推送到当前工作线程deque的末尾。
阻塞注释策略
blocking
函数用于注释执行阻塞操作的代码段,无论是通过发出阻塞系统调用还是执行任何长时间运行的CPU密集型计算。
处理阻塞闭包的策略是将工作线程传递给新线程。这意味着将 deque
和 mpsc
传递。一旦完成,新线程将继续处理工作队列,而原始线程可以阻塞。一旦它完成处理阻塞的futures,该线程没有更多工作,并被插入到备用池中。这使得它可供遇到 blocking
调用的其他工作线程使用。
依赖项
~1.5MB
~25K SLoC