簡體   English   中英

node.js 中 setInterval() 的奇怪行為(僅限 Windows,適用於 linux)

[英]Odd behavior with setInterval() in node.js (windows only, works in linux)

我在使用 windows 機器的 node.js 中遇到了一些奇怪的問題,這在 linux 機器上不會發生。

在低延遲設置(< 100 毫秒)下使用 setInterval() function 時:本質上,所提供的 function 的調用頻率比我預期的要少,方式非常一致。 當使用我在下面快速寫下的示例代碼時,windows 機器似乎始終給出與 linux 機器不同的結果,即使在相同的硬件上運行也是如此。

//should be time in MS between executions
var delay = 10;

//how many seconds to run the test
var testPeriods = 10;

var counter = 0;
var startTime = new Date().getTime();

var interval = setInterval(() => {
    ++counter;
    if (new Date().getTime() >= startTime+1000*testPeriods) {
        console.log('Mean Function Calls per Second:', counter/testPeriods);
        clearInterval(interval);
    }
}, delay);

一些測試數據,來自我的雙引導 linux 和 windows 的電腦:

Delay (ms) | Expected | Linux result | Windows result
-----------+----------+--------------+---------------
       100 |       10 |         10.0 |            9.2
        50 |       20 |         20.0 |           16.0
        25 |       40 |         39.8 |           32.0
        10 |      100 |         98.4 |           63.8

您會注意到 linux 結果幾乎完全匹配,直到較低的延遲設置,即使它們也相差不遠。 另一方面,windows 結果遠遠不夠。

我認為與 linux 版本相比,節點的 windows 版本的優化可能很差。 所以起初,我假設我提供的 function 執行時間太長,從而延遲了下一次執行。 然而,情況似乎並非如此。 畢竟,如果我假設所提供的 function 無論如何都需要類似的時間來執行,那么我知道 windows 機器可以在最低延遲設置下每秒最多執行約 63 次。 那么為什么它只執行~32次,而它應該執行~40次(延遲@ 25ms)?

如果有人可以讓我了解為什么會發生這種情況或我做錯了什么,那將不勝感激。

編輯:在@jfriend00 的建議下簡化了代碼,並更新了測試結果以匹配。

一段預定代碼的調用速度取決於您的操作系統的定時器中斷間隔。 根據操作系統,此設置稱為tickjiffy 在某些操作系統上,它是可配置的。

操作系統將定期運行自己的代碼來執行檢查,例如讓進程輪流使用 CPU、清理 memory 等。為此,操作系統設置了一個定時器中斷(實際上它就像setInterval僅在硬件級別)來運行自己的代碼。

這實際上是操作系統如何設法運行比可用內核更多的進程/線程,並且正是這種機制在操作系統級別驅動 javascript 中的setIntervalsetTimeout 所以基本上線程和setInterval都使用相同的 OS 機制,唯一的區別是線程可以同時使用多個內核,而setInterval只能使用與主 js 線程相同的內核。

您設置刻度的頻率需要權衡取舍。 刻度設置得很短將使您的操作系統更加實時,因為事件處理的延遲大大減少。 但是,這也意味着您的操作系統代碼使用更高百分比的 CPU 時間,而留給您的應用程序的時間更少。 刻度設置得更長將為您的應用程序提供更多的 CPU 時間,從而為您提供更多的吞吐量。

我實際上對你的結果有點驚訝。 幾年前(2000 年代初),Linux 上的默認jiffy設置相當長,因為 Linux 針對服務器使用進行了更多優化,因此針對吞吐量進行了優化。 另一方面,Windows 的刻度較短,因為 Windows 針對玩游戲和運行圖形應用程序等實時任務進行了更多優化。 也許這些年來情況發生了變化。

所以是的,如果你想要跨平台的一致性,那么有一個最小的setInterval時間可以跨操作系統工作。 但是我猜想 10 毫秒就足夠了,因為這是我多年來的經驗(1 毫秒顯然會顯示各種操作系統的不同行為)。 如果這些天 10 毫秒不起作用,您可以嘗試更長的時間間隔,例如 50 毫秒‡ 或 100 毫秒。

‡ 注意:50ms 或 20fps 是無線電控制發射器的更新間隔,因此它是實時的,足以讓人類反應駕駛飛機、直升機和無人機而不會墜毀

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM