Mio 在零持续时间超时的轮询中的行为是啥?
Posted
技术标签:
【中文标题】Mio 在零持续时间超时的轮询中的行为是啥?【英文标题】:What is Mio's behaviour on a Poll with a zero duration timeout?Mio 在零持续时间超时的轮询中的行为是什么? 【发布时间】:2018-04-11 16:08:21 【问题描述】:根据mio::Poll
docs:
该函数将一直阻塞,直到至少收到一个就绪事件或超时已过。超时 None 意味着 poll 将阻塞,直到收到准备就绪事件。 ... 注意超时时间会向上取整到系统时钟粒度(通常为1ms),内核调度延迟意味着阻塞间隔可能会被少量超限。
同时,Linux 的select()
has the zero timeout feature:
如果 timeval 结构的两个字段都为零,则 select() 立即返回。 (这对轮询很有用。)
Mio 在 Duration::from_secs(0)
上的行为是什么,它会像 Linux 的 select()
一样工作吗?
【问题讨论】:
【参考方案1】:我想你想要一个 Linux 答案,因为你链接到 Linux 手册。
mio
uses epoll()
, not select()
, on Linux:
/// | OS | Selector |
/// |------------|-----------|
/// | Linux | [epoll] |
/// | OS X, ios | [kqueue] |
/// | Windows | [IOCP] |
/// | FreeBSD | [kqueue] |
/// | android | [epoll] |
epoll()
的相关引用是:
timeout 参数指定 epoll_wait() 将阻塞的最小毫秒数。 (这个时间间隔会向上取整到系统时钟粒度,内核调度延迟意味着阻塞间隔可能会被少量溢出。)指定超时时间为-1会导致epoll_wait()无限期地阻塞,同时指定超时时间等于零导致 epoll_wait() 立即返回,即使没有可用的事件。
所以,Duration::from_secs(0)
不会等待传入事件。可以查看mio
here的代码
let timeout_ms = timeout
.map(|to| cmp::min(millis(to), i32::MAX as u64) as i32)
.unwrap_or(-1);
我们可以看到mio
的行为会复制epoll()
的行为。
【讨论】:
我想知道你是否知道为什么你最后一段中引用的代码是as u64
,然后返回as i32
。为什么不在整个表达式中保留i32
?
@ZanLynx millis()
返回一个u64
,为了避免溢出,因为超时是一个 C int
(他们假设 C int
有 32 位),他们将此值与 @ 进行比较987654340@ 要做到这一点,需要先将其转换为 u64,然后取最小值,因此最终结果是肯定的并且不能溢出 i32
。以上是关于Mio 在零持续时间超时的轮询中的行为是啥?的主要内容,如果未能解决你的问题,请参考以下文章