一個進程最多可以創建線程的數目

轉載自:http://blog.csdn.net/gtyi999/article/details/50404611

(1)在x86平臺32位系統,系統佔用2GB地址空間,用戶方式2GB。如果使用VS,鏈接程序開關/SACK 或者/F可以設置線程堆棧大小,默認分配一個線程的堆棧大小是1MB,當CreateThread參數的StackSize大小與鏈接程序設置的不一致時,採用的方法是誰大用誰的,所以用4KB修改當然不會有改變!理論上最大線程數=2GB/1MB=2048。

實際上這個用戶方式的2GB並不會全部用作線程堆棧。首先程序的代碼和數據、進程環境塊、線程環境塊、空指針區域等等也需要佔用一定的地址空間;再者2GB只是虛擬內存,如果非分頁內存被用完,就無法再創建線程,這個與特定機器有關,所以不同機器上做最大線程數測試得到的數字可能不一樣。

(2)操作系統給一個系統進程提供的空間是2GB ,而一個線程堆棧的空間默認在啓動的時候是1MB 那麼啓動完2000後,基本上就有2GB了,你可以減小默認堆棧的大小。

(3)默認情況下,一個線程的棧要預留1M的內存空間而一個進程中可用的內存空間只有2G,所以理論上一個進程中最多可以開2048個線程
但是內存當然不可能完全拿來作線程的棧,所以實際數目要比這個值要小。你也可以通過連接時修改默認棧大小,將其改的比較小,這樣就可以多開一些線程。如將默認棧的大小改成512K,這樣理論上最多就可以開4096個線程。即使物理內存再大,一個進程中可以起的線程總要受到2GB這個內存空間的限制。比方說你的機器裝了64GB物理內存,但每個進程的內存空間還是4GB,其中用戶態可用的還是2GB。如果是同一臺機器內的話,能起多少線程也是受內存限制的。每個線程對象都要站用非頁面內存,而非頁面內存也是有限的,當非頁面內存被耗盡時,也就無法創建線程了。
如果物理內存非常大,同一臺機器內可以跑的線程數目的限制值會越來越大。

  在Windows下寫個程序,一個進程Fork出2000個左右線程就會異常退出了,爲什麼?

  這個問題的產生是因爲windows32位系統,一個進程所能使用的最大虛擬內存爲2G,而一個線程的默認線程棧StackSize爲1024K(1M),這樣當線程數量逼近2000時,2000*1024K=2G(大約),內存資源就相當於耗盡。

(4)默認每線程1MB堆棧的話,只能開2048線程(如果你的其它系統資源足夠的話)。要想開更多線程,只能修改每個線程的堆棧,但實際中是不推薦這樣做的,因爲如果你的線程因爲一些工作因爲線程堆棧不夠的話,會導致整個進程崩潰.修改堆棧的方法好像只在XP或以上系統有效,windows 2000中不支持。

發佈了160 篇原創文章 · 獲贊 48 · 訪問量 29萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章