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 手册。

miouses 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) 不会等待传入事件。可以查看miohere的代码

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 在零持续时间超时的轮询中的行为是啥?的主要内容,如果未能解决你的问题,请参考以下文章

如何从长轮询中获取响应数据?

JQuery中发布-订阅模式在网络可用性轮询中的实现

如何从 jenkins 作业的 scm 轮询中排除 jenkins 文件

SQS 短轮询是不是比长轮询更可取?

如何在 Truffle 中配置不同的轮询间隔?

长轮询如何工作 javascript?