需要一个循环睡眠几分之一秒

use*_*079 16 scripting bash

在我的机器上,我需要执行一个循环来迭代 1 个简单命令,该命令必须具有以几分之一秒表示的延迟。

假设我需要:

  • 保存具有递增枚举( file-0, file-1, file-2, ... )的文件 time > file-$x
  • 我需要每 1/70 秒执行一次(例如),因为我想用几分之一秒来表达我的时间。

我如何才能真正精确并用 bash 脚本表达所有内容?

分数可以产生一个无法确定的数量,我需要精确,所以我至少需要 4-5 位小数。

Rob*_*Bos 12

要在 bash 中将分数转换为小数,请执行以下操作

myvar=$(echo "scale=4; 5/10" | bc)
Run Code Online (Sandbox Code Playgroud)

然后,要对该值进行循环,

for i in $(seq 1 1000); do sleep $myvar; done
Run Code Online (Sandbox Code Playgroud)

我在 Debian (GNU) 上的睡眠实现似乎接受十进制睡眠值。

很遗憾..

有了这种精度(4-5 个小数位),您将需要类似 perl 脚本或编译程序的东西;在循环中调用任何程序的开销会增加很多抖动。调用 sleep 本身需要几毫秒。

考虑以下情况,1/10,000 秒的睡眠,完成 1000 次:

time for i in $(seq 1 1000); do sleep 0.0001; done

real    0m2.099s
user    0m3.080s
sys     0m1.464s
Run Code Online (Sandbox Code Playgroud)

预期的结果是 1/10 秒。睡眠远没有你想要的容忍度。

/sf/ask/62783311/

使用 perl 的 Time::HiRes, 1000*1000 微秒:

my $i=0;
for($i=0;$i<=1000;$i++) {
        usleep(1000);
}

real    0m1.133s
user    0m0.024s
sys     0m0.012s
Run Code Online (Sandbox Code Playgroud)

让我们更接近一秒钟。


Gil*_*not 8

也许你可以简单地运行

sleep 0.7
Run Code Online (Sandbox Code Playgroud)

?

man 1 sleep
Run Code Online (Sandbox Code Playgroud)

在我的archlinux发行版上:

描述 暂停 NUMBER 秒。后缀可以是 's' 表示秒(默认),'m' 表示分钟,'h' 表示小时或 'd' 表示天。与大多数要求 NUMBER 是整数的实现不同,这里的 NUMBER 可以是任意浮点数。给定两个或更多参数,暂停由它们的值之和指定的时间量。


Sté*_*las 6

生成一个进程并在其中加载一个新的可执行文件可能需要几毫秒,因此这种精度实际上没有意义。另请注意,许多系统上的 CPU 时间按最多 10 毫秒的切片分配给进程。

话虽如此,一些sleep实现需要秒的小数部分,zsh 和 ksh93 都可以$SECONDS使用typeset -F SECONDS.

示例(zsh):

$ typeset -F SECONDS=0; for ((i=1; i<=70; i++)); do sleep $((1./70)); date +%s.%N; done | { head -n3;echo ..;tail -n3; }; echo $SECONDS
1350076317.374870501
1350076317.391034397
1350076317.407278461
..
1350076318.464585550
1350076318.480887660
1350076318.497133050
1.1393780000
Run Code Online (Sandbox Code Playgroud)

哎呀,飘了。您可以根据以下条件调整睡眠时间$SECONDS

$ typeset -F SECONDS=0; for ((i=1; i<=70; i++)); do sleep $((i/70. - SECONDS)); date +%s.%N; done | { head -n3;echo ...;tail -n3; }; echo $SECONDS
1350076420.262775654
1350076420.277012997
1350076420.291302750
../..
1350076421.219682227
1350076421.234134663
1350076421.248255685
1.0020580000
Run Code Online (Sandbox Code Playgroud)

那些额外的 2 毫秒可能用于运行最后一个sleepdate命令。

另请注意, zsh 具有zselect以百分之一秒表示的内置超时。并且 ksh93 已sleep内置(并接受浮点数)并且printf可以打印日期/时间。

$ typeset -F SECONDS=0; for ((i=1; i<=70; i++)); do ((i<4 || i>67)) && printf '%(%S.%N)T\n' now; sleep $((i/70.-SECONDS)); done; echo $SECONDS
20.823349000
20.837510000
20.851663000
21.780099000
21.794254000
21.808405000
0.9992358685
Run Code Online (Sandbox Code Playgroud)

如果您想要更精确的东西,您可能需要实时操作系统或具有实时功能的操作系统当然不要使用外壳。