簡體   English   中英

Sleep(10)什么都不做?

[英]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發出信號的一個線程。

這激發了我嘗試將AutoResetEventSleep更改為WaitOne的方法,該方法僅用作睡眠的替代方法,在我的情況下,睡眠似乎不起作用。

嘗試了一下,它起作用了!

暫無
暫無

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

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