之前被教導盡量使用 ThreadPool,因為它會幫我們管理 Thread,但是卻沒有注意到使用上的一些細節。
因為 Thread 的使用相當耗費資源,而 ThreadPool 會幫我們管理 Thread 的生成,讓我們可以重複的使用 Thread,使我們的程式更有效率。但為了讓重用 Thread,ThreadPool 預設以 Processor 的數量來決定 ThreadPool 中最少的 Thread 數,例如: 我的電腦 (下圖) 有 2 Cores, 4 Logical Processors,ThreadPool 最少有四條 Thread (worker thread: 4, completion port thread: 4)。

因為 ThreadPool 中 Thread 一開始的數量只有四條 (以我的例子來說),所以當同一時間很多工作被放到 ThreadPool 的佇列中,而這些工作沒辦法在短時間消化完的情況下,ThreadPool 會開始建立新的 Thread 來執行這些工作,但是建立 Thread 的速度很慢,大約每秒建立一到兩個 Thread。
這也就是為什麼程式會看起來像是不動了一樣,因為這些工作透過 ThreadPool 去執行,但是 Thread 已經用完了,卻沒有 Thread 來做這些新的工作,必須等待 ThreadPool 建立新 Thread。所以過幾秒後,才又有可用的 Thread 來完成新的工作,這時程式才又有回應。
所以排入 ThreadPool 中的工作,執行的時間最好不要太長,否則後面排入的工作可能就要等很久才會執行到,這樣就餓死拉 (ThreadPool Starvation)。
主要參考的文章: https://blogs.msdn.microsoft.com/vancem/2018/10/16/diagnosing-net-core-threadpool-starvation-with-perfview-why-my-service-is-not-saturating-all-cores-or-seems-to-stall/
沒有留言:
張貼留言