另,進程 & 線程的很多知識可以看這里:http://www.cnblogs.com/charlesblc/p/6135666.html
今天查了一下進程和線程的資源占用。
比如問:棧和堆的大小?
答:棧是線程的概念,堆是進程的概念。
線程棧的大小,通過 ulimit -s 來設定。Linux默認是10240,也就是10M,Windows默認是1M.
堆的大小,一般最大是 虛擬空間大小 - 1G內核空間大小 - 全局空間等部分,還跟尋址有關。
進程的大小,比線程,還多出了一個PCB(描述進程基本情況和運行狀態),另外程序段,也是放在進程里的,線程保存的程序計數器、一組寄存器,和棧。
socket套接字其實都是打開的文件句柄,只要文件句柄夠用,socket套接字就夠用。
雖然端口port只有65535,並且1024以下的還被保留了;但是socket是四元組,本地同一個端口可以對應遠端多個IP和多個端口。
所以理論上這個四元組可以很多很多,網上有人說是 2的48次方。
更多的可以看《程序員的自我修養》。雖然我也不知道相關內容有沒有。
切換代價
進程和線程的切換代價,一直是對比的重點。下面羅列一下:
進程間切換的步驟:
1,保存程序計數其以及其他寄存器。
2, 更新當前處於“運行態”的進程的進程控制塊,把進程狀態改為相應狀態,更新其他相關域
3, 把被切換進程的進程控制塊移到相關狀態的隊列
4, 選擇另外一個進程開始執行,把該進程進程控制塊的狀態改為“運行態”
5, 恢復被選擇進程的處理器在最近一次被切換出運行態時的上下文,比如載入程序計數器以及其他處理器的值。
進程間切換伴隨着兩次模式切換(用戶--內核,內核--用戶)。
(同一進程內)線程間切換的步驟:
線程分兩種,用戶級線程和內核級線程
在用戶級線程中,
有關線程管理的所有工作都由應用程序完成,內核沒有意識到線程的存在。
用戶級線程間切換時,只需要保存用戶寄存器的內容,程序計數器,棧指針,不需要模式切換。
缺點:
1, 在進程的某個線程執行系統調用時,不僅該線程被阻塞,該線程所在進程的所有線程都被阻塞
2, 無法利用多處理器
在內核級線程中,
有關線程的管理工作都是由內核完成的,應用程序部分沒有線程管理的權限,只有一個接口(API)
內核級線程間切換時,除了保存上下文,還要進行模式切換。(看起來跟進程切換差不多,但不需要切換內存,緩存等,下面有詳細描述)
優點:
1, 可以利用多處理器
2, 線程阻塞不會導致進程阻塞
這一篇,講的更具體一些:http://blog.csdn.net/mba16c35/article/details/43382737
進程切換分兩步
1.切換頁目錄以使用新的地址空間
2.切換內核棧和硬件上下文。
對於linux來說,線程和進程的最大區別就在於地址空間。
對於線程切換,第1步是不需要做的,第2是進程和線程切換都要做的(但是仍然有不同,見下)。所以明顯是進程切換代價大。
線程上下文切換和進程上下文切換一個最主要的區別是線程的切換虛擬內存空間依然是相同的,但是進程切換是不同的。這兩種上下文切換的處理都是通過操作系統內核來完成的。內核的這種切換過程伴隨的最顯著的性能損耗是將寄存器中的內容切換出。
另外一個隱藏的損耗是上下文的切換會擾亂處理器的緩存機制。簡單的說,一旦去切換上下文,處理器中所有已經緩存的內存地址一瞬間都作廢了。還有一個顯著的區別是當你改變虛擬內存空間的時候,處理器的頁表緩沖(processor’s Translation Lookaside Buffer (TLB))或者相當的神馬東西會被全部刷新,這將導致內存的訪問在一段時間內相當的低效。但是在線程的切換中,不會出現這個問題。
