新的Timer实现
祝所有人快乐!
为了结束一个伟大的一周,有一个[新发布]的Tokio。这个版本 包括一个全新的计时器实现。
定时器
有时(通常),人们想要执行与时间相关的代码。也许是 功能需要在特定时刻运行。也许阅读需要有限 到固定的时间。为了处理时间,需要访问计时器!
历史
tokio-timer
箱子已经存在了一段时间。它最初建成
使用[哈希定时器轮] [轮](pdf警告)。它的粒度为100
毫秒,因此任何超时设置的分辨率都小于100毫秒
会被围捕。通常,在基于网络的应用程序的上下文中,
这可以。超时通常至少30秒,并不需要很高
精确。
但是,有些情况下100毫秒太粗糙。而且, Tokio计时器的原始实现有一些恼人的错误,但没有 由于实施策略,处理边缘案例非常好。
一个新的开始
计时器已从头开始重写并作为[tokio-timer
发布
0.2] 2。在大多数情况下,API非常相似,但实现是
完全不同。
它不使用单个哈希定时器轮实现,而是使用 分层方法(也在上面链接的论文中描述)。
计时器使用六个不同的级别。每个级别都是一个包含64的散列轮 插槽。最低级别的插槽代表一毫秒。该 下一级别表示64毫秒(1 x 64个插槽),依此类推。所以,一个插槽 每个级别的时间与下面的整个级别相同。
设置超时后,如果距离当前时刻64毫秒内, 它处于最低水平。如果超时在64毫秒和4,096之间 毫秒,它进入第二级,依此类推。
随着时间的推移,最低级别的超时被触发。一旦结束了 达到最低级别,从中删除下一级别的所有超时 水平并移至最低水平。
使用此策略,所有计时器操作(创建超时,取消a 超时,触发超时)是不变的。这导致非常好的性能 即使有很多突出的超时。
快速浏览一下API
如上所述,API并没有真正改变。主要有三个 类型:
还有一个简单的例子:
use tokio::prelude::*;
use tokio::timer::Delay;
use std::time::{Duration, Instant};
fn main() {
let when = Instant::now() + Duration::from_millis(100);
let task = Delay::new(when)
.and_then(|_| {
println!("Hello world!");
Ok(())
})
.map_err(|e| panic!("delay errored; err={:?}", e));
tokio::run(task);
}
上面的例子创建了一个新的Delay
实例,它将完成100
将来的毫秒数。 new
函数接受Instant
,所以我们计算
when
是从现在起100毫秒的瞬间。
一旦到达瞬间,“延迟”未来就会完成,从而产生
and_then
块被执行。
此版本附带一个简短的[指南],解释如何使用计时器和[API 文档】API。
集成在运行时中
使用计时器API需要运行计时器实例。 Tokio [运行时] 为您完成所有设置。
当使用tokio :: run
或通过调用Runtime :: new
启动运行时
直接启动线程池。每个工作线程将获得一个计时器
实例。所以,这意味着如果运行时启动了4个工作线程,那么就会有
是4个计时器实例,每个线程一个。这样做可以不使用计时器
支付同步成本,因为计时器将位于同一个线程上
作为使用各种计时器类型的代码(Delay
,Deadline
,Interval
)。
有了这个,周末愉快!