簡體   English   中英

C# - 使用Thread.Sleep()讓我的循環每秒運行幾百次

[英]C# - using Thread.Sleep() to get my cycle run several hundred times per second

我正在開發一個分析實時財務數據的應用程序。 目前我的主要計算周期有以下設計:

long cycle_counter=0;
while (process_data)
{
  (analyse data, issue instruction - 5000 lines of straightforwasrd code with computations)
  cycle_counter++;
  Thread.Sleep(5);
}

當我在我的筆記本(一個Core i5)處理器上運行這個應用程序時,循環每秒運行200-205次 - 這是一種預期的(如果你不打擾為什么它每秒運行超過200次)。

但是當我在具有2個6核Xeon處理器和24 GB快速RAM的“真實”工作站上部署應用程序,並且在大約3秒內加載Win7時,應用程序每秒運行大約67次。

我的問題是:

  • 為什么會這樣?

  • 在這種情況下,如何影響每秒的運行次數?

  • 有沒有更好的解決方案,每秒運行200-1000次循環? 我現在正在考慮刪除Thread.Sleep()(我在這里使用它的方式受到了很多批評)。 有12個內核,我只使用一個內核就可以解決這個問題。 但是我的解決方案有一些缺點嗎?

謝謝你的想法。

你正在采取的方法從根本上被打破了。 輪詢策略通常是一種不好的方法,並且任何時候你出於“我想將剩下的時間片還給操作系統”之外的其他原因進行睡眠時,你可能做錯了什么。

解決問題的更好方法是:

  • 創建未處理工作的線程安全隊列
  • 創建一個將新工作放入隊列的線程
  • 創建n個線程,將工作從隊列中取出並完成工作。 n應該是你減去一個CPU的數量。 如果你有超過n個線程,那么至少有兩個線程會占用CPU時間,這會讓它們變得更慢!
  • 工作線程什么也不做,只是坐在一個循環中,將工作從隊列中取出並完成工作。
  • 如果隊列為空,則“取出工作”
  • 當新工作到達時,其中一個被阻止的線程將被重新激活。

如何使用這些屬性構建隊列是一個着名的問題,稱為生產者/消費者問題。 關於如何執行阻塞生產者 - 消費者隊列的任何許多實現,有很多文章。 我建議找一個現有的調試版,而不是試着寫自己的; 做得對可能很棘手。

睡眠的分辨率由當前的計時器滴答間隔決定,通常為10或15毫秒,具體取決於Windows的版本。 但是,可以通過發出timeBeginPeriod命令來更改此設置。 看到這個答案

Windows不是RTOS(實時操作系統),因此您無法准確確定線程何時恢復。 Thread.Sleep(5)真的意味着“在5ms之后叫醒我”。 實際的休眠時間由特定硬件決定,主要由系統負載決定。 您可以嘗試通過以更高優先級運行應用程序來解決system load問題。

順便說一句, System.Threading.Timer是一種更好的方法(上面的評論仍然適用)。

檢查計時器的實際頻率 :許多硬件計時器具有實際分辨率

  65536 ticks per hour = 65536 / 3600 = 18.204 ticks per second 

所謂的“18.2”常數,這就是實際定時器的分辨率為1 / 18.2 = 55 ms的原因 ; Sleep(5)的情況下,它意味着可以是Sleep(0)Sleep(55)具體取決於向上舍入。

不確定這是最好的方法,但另一種方法。
嘗試BlockingCollection,你在生產者中所做的只是添加和睡眠。
然后,消費者可以選擇在需要時全職工作。
這仍然無法解釋為什么更高功率的PC運行更少的周期。

您可以平均每秒運行200次循環嗎?

var delay = TimeSpan.FromMillseconds(5);
while (process_data) {
    Console.WriteLine("do work");
    var now = DateTime.Now;
    if (now < nextDue) 
        System.Threading.Thread.Sleep(nextDue - now);
    nextDue = nextDue.Add(delay);
}

使用這種技術,你的循環會有點磕磕絆絆,但它平均應該沒問題,因為代碼既不依賴於Sleep的分辨率也不依賴於DateTime.Now的分辨率。

您甚至可以將此方法與Timer結合使用。

暫無
暫無

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

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