Virtualbox

睡眠命令延遲嚴重不准確 (VM)

  • September 3, 2020

我需要sleep在 shell 腳本中使用,所以我在終端中試用了它,但它產生的延遲不一致且非常不准確。例如sleep 3產生接近 20 秒的延遲。當指定相同的時間時,這些延遲也會波動。一般來說,延遲似乎隨著值的增加呈指數增長。

在 Ubuntu 和 Debian VM 上都進行了嘗試,結果同樣糟糕。我不認為 VM 組件在起作用(timeout 10在 Windows VM 上執行 a 很好)。

通過對每個命令進行計時,系統時鐘認為它執行正常,但實際上並非如此。請參閱下面的幾個範例。


括號中的時間是實際經過的時間(近似值):

$ time sleep 1        (7 secs)

real    0m1.040s
user    0m0.003s
sys     0m0.016s
$ time sleep 1        (5 secs)

real    0m1.028s      
user    0m0.009s
sys     0m0.013s
$ time sleep 1        (5 secs)

real    0m1.027s
user    0m0.013s
sys     0m0.007s
$ time sleep 1        (5 secs)

real    0m1.029s
user    0m0.007s
sys     0m0.016s
$ time sleep 3       (17 secs)

real    0m3.036s
user    0m0.000s
sys     0m0.021s
$ time sleep 5       (29.5 secs)

real    0m5.026s
user    0m0.007s
sys     0m0.013s

預設值顯然以秒為單位,但s在時間上添加一個並沒有任何區別。

主機上沒有執行其他可能佔用磁碟或 CPU 的設備。

在最初的幾次嘗試中,重新啟動 VM 似乎可以改善這種情況,但在那之後,準確性變得越來越差。

關於問題可能是什麼的任何想法?

編輯

  • 跑步declare -p PS1回報
declare -- PS1="\${debian_chroot:+(\$debian_chroot)}\\u@\\h:\\w\\\$ "
  • 跑步command -V sleep回報
sleep is hashed (/usr/bin/sleep)
  • 跑步declare -p PATH回報
declare -x PATH="/home/debwp/mycmds:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games"
  • Paul_Pedant 文章的結果:
~$ date '+%T.%N'; time sleep 5; date '+%T.%N'
22:47:49.679497552
^[[A
^[[A
^[[A
^[[A

real  0m5.033s
user  0m0.005s
sys   0m0.014s
22:47:54.788302324
~$ date '+%T.%N'; time sleep 5; date '+%T.%N'
22:47:54.830674809

real  0m5.043s
user  0m0.008s
sys   0m0.012s
22:47:59.934542825
~$ date '+%T.%N'; time sleep 5; date '+%T.%N'
22:47:59.994006022

real  0m5.057s
user  0m0.004s
sys   0m0.018s
22:48:05.159303996
~$ date '+%T.%N'; time sleep 5; date '+%T.%N'
22:48:05.241043114

real  0m5.099s
user  0m0.004s
sys   0m0.021s
22:48:10.383158635
~$ date '+%T.%N'; time sleep 5; date '+%T.%N'
22:48:10.435520982

real  0m5.028s
user  0m0.004s
sys   0m0.012s
22:48:15.497877219
~$
  • date以每秒〜一次的速度進入終端導致
$ date
Mon 31 Aug 20:42:25 CEST 2020
$ date
Mon 31 Aug 20:42:25 CEST 2020
$ date
Mon 31 Aug 20:42:25 CEST 2020
$ date
Mon 31 Aug 20:42:26 CEST 2020

在 VirtualBox guest的時鐘漂移中找到了這個答案

在 Virtualbox Manager 中,將準虛擬化值(系統設置 –> 加速選項卡)從Default更改為Minimal更正問題。

該行為肯定與您的管理程序有關。

time(7)說:

實時定義為從某個固定點測量的時間,或者從過去的標準點(參見下面的紀元和日曆時間的描述),或者從流程生命中的某個點(例如,開始)(經過的時間)。

程序時間定義為程序使用的 CPU 時間量。這有時分為使用者和系統組件。使用者 CPU 時間是在使用者模式下執行程式碼所花費的時間。系統 CPU 時間是核心在系統模式下代表程序執行(例如,執行系統呼叫)所花費的時間。time(1) 命令可用於確定程序執行期間消耗的 CPU 時間量。

基於此,我們可以得出結論,當我們編寫時:

$ time sleep 1

real    0m1.002s
user    0m0.002s
sys     0m0.000s

real是實時時間,表示過程中花費的實際時間(有時稱為掛鐘時間)。 user是在使用者模式下執行程式碼sys所花費的 CPU 時間(CPU 週期 * 頻率),並且是核心代表程序在系統模式下執行所花費的 CPU 時間(CPU 週期 * 頻率)。

解釋你的問題:

為什麼我的手錶不real報告時間?time(1)

當您在裸機上執行作業系統時,通常會有一個以恆定頻率執行的電池供電的晶體振盪器。該硬體時鐘將跟踪自紀元以來的時間。可以調整每秒的振盪次數以校正漂移(請參閱hwclock(8))。

time(7)還說:

設置超時的各種系統呼叫(例如 select(2)、sigtimedwait(2))和測量 CPU 時間(例如 getrusage(2))的準確性受到軟體時鐘的解析度的限制,該時鐘由以 jiffies 為單位測量時間的核心。jiffy 的大小由核心常數 HZ 的值決定。

硬體時鐘用於初始化系統時鐘(否則它只會知道自啟動以來的時間)。我懷疑您的管理程序(虛擬機)使用一些 hwclock 來初始化時間。之後,軟體時鐘接管。

rtc(4)說:

$$ hardware clocks $$不應與系統時鐘混淆,系統時鐘是由核心維護的軟體時鐘,用於實現 gettimeofday(2) 和 time(2),以及設置文件的時間戳等。

我們剛剛在這裡學到的是time(2)(這是實用程序使用的庫呼叫time(1))實際上是從系統時鐘而不是硬體時鐘獲取資訊。

軟體時鐘由測量時間的核心維護jiffies。這是由核心常數確定的時間單位。據我了解,一定數量的 CPU 週期會增加一個 jiffie。因此,如果作業系統認為 CPU 執行在 2.0 GHz,但 CPU 實際上執行在 1.0 GHz,那麼與掛鐘相比,一個 jiffie 實際上需要 2 毫秒,而不是預期的 1 毫秒。

當使用物理硬體執行時,我們告訴 CPU 我們希望它執行多快(為了省電而執行更慢,性能更快),然後我們假設硬體實現了它所承諾的,因為物理硬體確實做到了。訣竅在於,當“硬體”是虛擬的時,管理程序決定如何控制虛擬 CPU,而不是物理定律。

在使用者空間(如虛擬盒)中執行的管理程序將受主機核心的支配,以為其提供所需的周期。如果主機系統執行 1000 個虛擬機,您可以想像每個來賓 VM 將只能獲得其預期的一部分 CPU 週期,從而導致猜測系統時鐘以較慢的速率增加。即使管理程序獲得了它需要的所有資源,它也可以選擇在它認為合適的時候限制資源,讓客戶作業系統執行得比它預期的要慢,而不知道為什麼。

引用自:https://unix.stackexchange.com/questions/607217