Dot-Net

多核使用、執行緒、執行緒池

  • November 21, 2012

我有一些關於多執行緒程式和多核使用的問題。

特別是我想知道作業系統和/或框架(這是.NET)如何處理大量使用的核心。

這是我關於執行緒的問題:

  • 當產生一個新執行緒時,將執行緒分配給特定核心的算法是什麼?

    1. 循環算法類型
    2. 隨機的
    3. 目前使用最少的核心
  • 如果不是目前使用最少的核心,那麼確定這種類型的程式碼是否會使執行緒的典型使用相形見絀,從而使事情變得更糟?

  • 執行緒在其生命週期內是否從一個核心移動到另一個核心?如果是這樣,這是為了處理由於某種原因被“過度使用”的核心,因此作業系統會嘗試將執行緒轉移到使用較少的核心以幫助系統?如果不是,再次,為什麼不呢?

我的最後一個問題,基本上是對上述內容的重用,是關於 .NET ThreadPool 類的,它處理諸如 .BeginInvoke 之類的事情。這門課做這些事情嗎?如果不是,為什麼不,或者應該這樣做?

有什麼方法可以調整這種處理方式,向作業系統暗示這個特定的執行緒,當你給它分配一個核心時請多加註意,因為我知道它會使用很多 cpu。這有意義嗎?或者“很多cpu”只是相對的,因此還不夠好?

當產生一個新執行緒時,將執行緒分配給特定核心的算法是什麼?

這完全取決於作業系統。答案通常是經過大量修改的循環方案。每 x 毫秒,一個核心被中斷,並在其上放置一個新執行緒(因此沒有“最少使用的核心”。只要有執行緒準備好執行,每個核心都會有事可做)。

在 Windows 中,我相信總是選擇優先級最高的執行緒/程序來執行。(因此,如果您有一個程序在單核系統上以高優先級執行,則該程序可能會在 100% 的時間內執行,從而使所有其他程序都處於飢餓狀態。當然,這僅適用於該程序從不阻塞的情況,這在現實中。

當然,因為像 Windows 這樣的現代作業系統很複雜,所以它還有很多其他功能。某些程序有時會得到優先處理,但根據經驗,Windows 總是會選擇高優先級程序(這就是為什麼你可以通過在單核時代給予程序“實時”優先級來幾乎凍結你的電腦)

在 Linux 下,優先級較低的程序也會定期調度,只是不那麼頻繁。

但你能做的最好的事情通常只是假設作業系統會制定一個公平的方案,然後嘗試與系統的其餘部分配合得很好。(當你無事可做時讓/阻塞/睡眠,允許其他執行緒執行)。

執行緒在其生命週期內是否從一個核心移動到另一個核心?

當然。假設您在雙核系統上執行三個執行緒。向我展示一個不涉及在核心之間定期移動執行緒的公平時間表。

我的最後一個問題,基本上是對上述內容的重用,是關於 .NET ThreadPool 類的,它處理諸如 .BeginInvoke 之類的事情。這門課做這些事情嗎?如果不是,為什麼不,或者應該這樣做?什麼東西?執行緒調度和選擇要執行的核心?不,執行緒池只是一種為多個任務重用執行緒的機制,而不是必須為每個任務創建一個新執行緒,然後再關閉它。

有什麼方法可以調整這種處理方式,在作業系統中暗示這個特定執行緒

這就是執行緒/程序優先級的用途。如果您有一個執行緒必須獲得大量 CPU 時間,即使有其他 CPU 密集型執行緒正在執行,也要提高執行緒的優先級。但要小心處理。通常,執行的 CPU 密集型執行緒並不多,這意味著即使在正常優先級下,您也將獲得 99.9% 的 CPU 時間。正如我所說,Windows 會非常積極地調度優先級更高的執行緒,所以只有在你真的認真時才提高優先級。

引用自:https://stackoverflow.com/questions/396137