[英]Sleep(10) does nothing?
我的Web服務遇到一個奇怪的情況。
這是一個簡單的例子-它創建了一個持續運行的線程,在后台對磁盤進行了一些磁盤檢查,並針對每個文件執行了它存在的工作后進入Sleep(10),因此它不會消耗所有CPU內核。
一切正常,直到我從RDP登錄。 當我這樣做時,該線程將峰值並消耗盡可能多的內存。
在這里,看看...
我有兩個核心,我的前台應用使用了大約18%的CPU(這在NOW-meter上顯示)。 左側是沒有登錄時的CPU使用率。
到底是怎么回事? 還有更多-在這種情況下如何適當地節制線程?
我的代碼片段產生了這個問題:
foreach (string fi in files)
{
if (_shouldStop)
{
break;
}
lock (_workItems)
{
StatusString = string.Format("Examining file Dir={0}\nmask={1}\nfile={2}\nqueue={3}",
root, mask, fi, _workItems.Count);
}
lock (_workItems)
{
if (!_workItems.Contains(fi))
{
if (!File.Exists(TargetForFile(fi + ".hash")))
{
StatusString = string.Format("Adding file Dir={0}\nmask={1}\nfile={2}\nqueue={3}",
root, mask, fi, _workItems.Count);
_workItems.Add(fi);
}
}
}
Thread.Sleep(10);
}
小更新:
當代碼作為Windows服務運行並且沒有人連接到計算機時,即使Sleep(1000)
也不起作用。 我正式宣布它為WTF。
別睡覺 而是將線程優先級設置為IDLE。
接下來的事情是確定每個進程的CPU消耗,因此您不會追趕紅鯡魚。 打開Perfmom.exe並查看Process(*)\\(*)
對象(所有實例)。 然后,您可以檢查每個進程的“ % Processor Time
和“ % User Time
,並確定在關閉RDP時誰在使用18%的內存。
附帶說明shuffling same directories over and over again
,為什么不shuffling same directories over and over again
,為什么不使用更改通知機制呢?
睡眠10僅為10毫秒-因此您真的接近屈服並重新開始工作。
我的猜測是,當您登錄時,已經發生了足夠的事情,因此您的線程不會立即被重新安排,因此它實際上最終會處於閑置狀態超過10毫秒(而且我認為我讀到的最大分辨率為睡眠是100米爾,順便說一句)。 但是,當您不使用RDP時,該線程變得可用於更頻繁地重新調度,因此它消耗了更多的CPU。
要進行測試,請嘗試將睡眠時間增加到500(0.5秒)或1000左右,以使您有明顯的睡眠時間。
另一個測試是在“什么都不做”循環中丟棄另一個線程,並在強制CPU繁忙時查看您的file.exists線程是否妥善處理。
當我登錄RDP時會遇到類似的高峰,而我沒有運行您的代碼。 奧卡姆(Occam)的剃刀暗示它是利用內核的RDP。
此外,如果您正在執行File.Exists,無論如何線程都會在磁盤I / O上阻塞,如果有一個點給CPU帶來了沉重負擔,那只會在執行完之后才會出現。
最后,如果您還沒有做過任何事情,例如從Normal提升進程優先級,那么它將與其他進程共享內核。 如果陷入一個緊密的循環,可能會有點不好,但是即使如此,調度程序也應該防止它自己造成太大的傷害。 如果您擁有多個內核,則對於Windows的最新版本尤其如此。
編輯:其實,全部。 為什么要自己循環輪詢而不是響應FileSystemWatcher事件。 設置一個或多個FileSystemWatcher
來監視感興趣的目錄,然后輪詢您所關心的特定文件存在更改以作為響應。 減少代碼的工作量,並且應該也具有更高的響應速度。
感謝您提供的所有答案,但我將嘗試提供我自己的一個。
我現在不需要更改體系結構,並且使用任何數量的Sleep()
任何嘗試都將失敗。 除了SO之外,我還搜索了其他一些網站,並發現Jon Skeet建議使用Monitor
發出信號的一個線程。
這激發了我嘗試將AutoResetEvent
的Sleep
更改為WaitOne
的方法,該方法僅用作睡眠的替代方法,在我的情況下,睡眠似乎不起作用。
嘗試了一下,它起作用了!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.