2010-01-10 52 views
0

我使用QueueUserWorkItem()函數來調用線程池。
我試了很多工作。 (約30000)
但由任務管理器我的應用程序只按了4〜5個線程後,我按下了開始按鈕。
我讀了MSDN,它表示線程限制的默認數量約爲500.
爲什麼只有少數線程在我的應用程序中生成?
我正在加快我的應用程序,我dout這個線程池是減慢我的應用程序的原因之一。

我的線程池只能做4〜5個線程。爲什麼?

感謝

回答

1

瞭解threadpool調度程序如何工作很重要。它旨在根據機器的功能微調運行線程的的數量。您的機器可能只能同時運行兩個線程,雙核CPU是當前的標準。也許四個。

所以,當你將一堆線程轉儲到它的膝上時,它通過僅激活兩個線程而開始。其餘的人在隊列中,等待CPU核心可用。只要這兩個線程中的一個完成,它就會激活另一個線程。它每秒兩次,評估未完成的活動線程發生了什麼。它粗略地假設那些線程被阻塞,因此沒有進展並且允許另一個線程激活。你現在有三個正在運行的線程。啓動500個線程(默認的最大線程數)需要249秒。

很明顯,這種行爲表明了一個線程應該做什麼來適合作爲線程池線程運行。它應該很快完成並且不會經常阻止。請注意,對I/O請求的阻止是分開處理的。

如果此行爲不適合您,則可以使用常規線程。它將立即開始運行,並與程序(和操作系統)中的其他線程競爭CPU時間。創建30,000個這樣的線程是不可能的,沒有足夠的虛擬內存可用於此。一個32位操作系統在2000線程以南的某個地方冒出來,消耗所有可用的虛擬內存。在分頁文件耗盡之前,您可以在64位操作系統上獲得大約50,000個線程。不建議在生產程序中測試這些限制。

+0

是的我發現我的機器有四個核心。沒有線程池我的應用程序運行速度慢了4倍。 –

0

線程池是有這樣就可避免針對其原因恰恰是線程是昂貴的每一個異步操作創建一個線程。如果你想要30,000個線程,你會爲線程堆棧使用大量的內存,並浪費了很多CPU時間來執行上下文切換。現在創建這麼多的線程是合理的,如果你有30,000個CPU核心...

1

我想你可能誤解了線程池的使用。產生線程和殺死線程涉及Windows內核,並且是一項昂貴的操作。如果您不斷需要線程來執行異步操作,然後將它們扔掉,則會執行很多系統調用。

所以線程池實際上是一組創建線程一旦而不是退出時,他們完成他們的任務實際上輸入等待另一個項目爲queueuserworkitem。線程池將根據您的進程需要併發多少個線程來調整自身。如果你想測試這個寫這個代碼:

for(int i = 0; i < 30000; i++) 
{ 
    ThreadPool.QueueUserWorkItem(myMethod); 
} 

你會看到這將創建一大堆線程。可能不是30000,因爲ThreadPool開始通過函數調用工作,所創建的一些線程將被重用。