AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题 / 778751
Accepted
Stéphane Chazelas
Stéphane Chazelas
Asked: 2024-06-21 20:26:41 +0800 CST2024-06-21 20:26:41 +0800 CST 2024-06-21 20:26:41 +0800 CST

Linux 上的 select() / poll() 超时延长

  • 772

在将这个答案写在这里给另一个问答时,我注意到 zsh 解决方案中用于休眠给定厘秒数的时间select()比我预期的要差很多。

这似乎是由于select()我的系统超时似乎有一个一致的漂移,就好像它的秒数值是正常秒数的 1.001 一样。

$ strace -qqTe /select zsh -c 'zmodload zsh/zselect; zselect -t 6000'
pselect6(0, 0x7ffcee6a9f60, 0x7ffcee6a9fe0, 0x7ffcee6aa060, {tv_sec=60, tv_nsec=0}, NULL) = 0 (Timeout) <60.058930>
$ strace -qqTe /select zsh -c 'zmodload zsh/zselect; zselect -t 600'
pselect6(0, 0x7ffcf2042b70, 0x7ffcf2042bf0, 0x7ffcf2042c70, {tv_sec=6, tv_nsec=0}, NULL) = 0 (Timeout) <6.006212>
$ uname -rs
Linux 6.7.12-amd64

看看 6 秒超时如何花费 6.006 秒,以及 60 秒超时如何花费 60.06 秒。

我在不同的硬件上观察到了同样的情况,Ubuntu 22.04 和 Linux 6.5.0。

相同,perl而不是zsh:

$ strace -qqTe /select perl -e 'select undef,undef,undef,60'
pselect6(0, NULL, NULL, NULL, {tv_sec=60, tv_nsec=0}, NULL) = 0 (Timeout) <60.060218>

同样,使用 poll() 代替 select():

$ strace -qqTe /poll perl -MIO::Poll -e 'IO::Poll->new()->poll(6)'
poll([], 0, 6000)                       = 0 (Timeout) <6.006215>
$ strace -qqTe /poll perl -MIO::Poll -e 'IO::Poll->new()->poll(60)'
poll([], 0, 60000)                      = 0 (Timeout) <60.060214>

这似乎不适用于clock_nanosleep()或alarm()。

这是一个已知问题吗?甚至可能是故意的吗?

linux
  • 1 1 个回答
  • 244 Views

1 个回答

  • Voted
  1. Best Answer
    Stephen Kitt
    2024-06-21T21:55:18+08:002024-06-21T21:55:18+08:00

    这是有意为之,尽管没有作为内核接口的一部分记录下来。select超时有一些余地,目前¹常规任务的超时为 0.1%,上限为 100 毫秒(“nice” 任务为 0.5%):

    /*
     * Estimate expected accuracy in ns from a timeval.
     *
     * After quite a bit of churning around, we've settled on
     * a simple thing of taking 0.1% of the timeout as the
     * slack, with a cap of 100 msec.
     * "nice" tasks get a 0.5% slack instead.
     *
     * Consider this comment an open invitation to come up with even
     * better solutions..
     */
    

    在安排超时时使用余地;它定义了内核出于功率或性能原因将唤醒移回的余地有多大。

    select由于时间是在设置计时器之前和唤醒任务之后花费的,​​因此这个余量并不是您在上看到的最大延迟;但它应该接近上限:

    $ for i in {1..10}; do strace -qqTe /select zsh -c 'zmodload zsh/zselect; zselect -t 6000'; done
    select(0, …, {tv_sec=60, tv_usec=0}) = 0 (Timeout) <60.060082>
    select(0, …, {tv_sec=60, tv_usec=0}) = 0 (Timeout) <60.058872>
    select(0, …, {tv_sec=60, tv_usec=0}) = 0 (Timeout) <60.058342>
    select(0, …, {tv_sec=60, tv_usec=0}) = 0 (Timeout) <60.038167>
    select(0, …, {tv_sec=60, tv_usec=0}) = 0 (Timeout) <60.037595>
    select(0, …, {tv_sec=60, tv_usec=0}) = 0 (Timeout) <60.059775>
    select(0, …, {tv_sec=60, tv_usec=0}) = 0 (Timeout) <60.058236>
    select(0, …, {tv_sec=60, tv_usec=0}) = 0 (Timeout) <60.060196>
    select(0, …, {tv_sec=60, tv_usec=0}) = 0 (Timeout) <60.057481>
    select(0, …, {tv_sec=60, tv_usec=0}) = 0 (Timeout) <60.059292>
    

    如果某项任务的计时器松弛量 ( /proc/pid/timerslack_ns) 高于计算出的select松弛量,则改用:

    $ for i in {1..10}; do strace -qqTe /select zsh -c 'echo 10000000 | sudo tee /proc/$$/timerslack_ns > /dev/null; zmodload zsh/zselect; zselect -t 600'; done 2>&1 | grep select
    select(0, …, {tv_sec=6, tv_usec=0}) = 0 (Timeout) <6.006330>
    select(0, …, {tv_sec=6, tv_usec=0}) = 0 (Timeout) <6.006650>
    select(0, …, {tv_sec=6, tv_usec=0}) = 0 (Timeout) <6.010218>
    select(0, …, {tv_sec=6, tv_usec=0}) = 0 (Timeout) <6.007780>
    select(0, …, {tv_sec=6, tv_usec=0}) = 0 (Timeout) <6.004928>
    select(0, …, {tv_sec=6, tv_usec=0}) = 0 (Timeout) <6.006641>
    select(0, …, {tv_sec=6, tv_usec=0}) = 0 (Timeout) <6.009273>
    select(0, …, {tv_sec=6, tv_usec=0}) = 0 (Timeout) <6.010185>
    select(0, …, {tv_sec=6, tv_usec=0}) = 0 (Timeout) <6.010173>
    select(0, …, {tv_sec=6, tv_usec=0}) = 0 (Timeout) <6.006746>
    

    减少懈怠的唯一方法就是使任务实时化:

    $ sudo strace -qqTe /select chrt 99 zsh -c 'zmodload zsh/zselect; zselect -t 600'
    select(0, …, {tv_sec=6, tv_usec=0}) = 0 (Timeout) <6.000141>
    

    ¹自 2008 年 2.6.28 起…

    • 9

相关问题

  • 有没有办法让 ls 只显示某些目录的隐藏文件?

  • 使用键盘快捷键启动/停止 systemd 服务 [关闭]

  • 需要一些系统调用

  • astyle 不会更改源文件格式

  • 通过标签将根文件系统传递给linux内核

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    模块 i915 可能缺少固件 /lib/firmware/i915/*

    • 3 个回答
  • Marko Smith

    无法获取 jessie backports 存储库

    • 4 个回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    user12345 无法获取 jessie backports 存储库 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl 为什么大多数 systemd 示例都包含 WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve