之前已經討論過進程了,現在討論線程。我在想如何用現實中的具體事物來比較進程和線程的關系。
舉個我認為較恰當的例子。把進程比作一個工廠中的車間,車間中有若干個生產線,但是每條生產線都需要不同的零件,原料和員工。零件,原料和員工,是所有生產線都可以共同使用的資源。這里就把生產線當做線程吧。這樣,每條生產線就只用管自己的生產過程。
就如討論進程一樣,這里還是列舉一下線程所包含的實體。
PRogram counter
Register
Statck
State
不難發現,線程關心的只是下一刻CPU執行所需的必要實體,只需要知道PC等寄存器的信息,當前棧指針,不用關心我有沒有子進程啊,我的地址空間在哪里,我打開了什么文件等等的信息。因為這些信息CPU已經知道了。
為什么要使用線程在《現代操作系統》中已經說明了使用線程的種種優勢,很容易就能看明白。其實根據上文,也能猜到答案。這里就不用說明了。
線程實現的方式線程可以在內核中實現,也可以在用戶空間實現。我自己的理解是這樣的:在內核中實現就是操作系統提供線程支持;在用戶空間中實現就是用戶自己實現。本來以為JVM的線程就是在用戶空間上實現的,但是搜了一下,貌似linux平臺下是調用Pthred庫實現的。這里還是深入學習一下這兩種線程的實現方式,為以后的工作和學習打下基礎,說不定什么時候就用上了。看了幾遍《現代操作系統》中的相關章節,可是自己還是云里霧里的,不是很清楚,這一次就好好的搞明白(不一定搞的明白,目前還沒有接觸過用戶空間實現的線程,也許是我孤陋寡聞)。
用戶空間實現線程在這種情況下,內核不知道線程的存在。當一個進程中的線程執行完畢,不需要進行系統調用(Trap),不需要進行上下文交換,所以線程的切換非??臁?/p>
但是在發生I/O中斷的時候,必須要內核去處理了。那么問題來了,內核會鎖住當前線程所在的進程,因為內核不知道線程的存在,只知道進程。解決這個辦法有點麻煩。《現代操作系統》中提出了一個解法,在某些UNIX版本中有一個select系統調用,它可以判斷I/O操作是否會阻塞。如果阻塞就不執行I/O操作。這樣run-time system(用的英文版教材,很多術語不會翻譯或者亂翻譯,囧)就知道是執行I/O,還是執行該進程的其它進程。
內核實現線程內核實現線程和進程區別不大。但是在線程被銷毀時,內核并不會銷毀線程的數據結構,只是會標記該線程是不可執行的。這樣,當新線程被創建時,覆蓋不可執行的線程的數據,效率大大的提高了。
還有一個問題,當一個多線程的進程執行fork時,子進程是否需要復制父進程的所有線程還是個別線程,如何操作。這個,因為很少接觸Linux下的C編程,所以暫時放在這里吧。
進程和線程的區別面試的時候,這個問題可能是問的最多的,可以考察歸納能力和是否理解進程和線程。這里給出自己的理解。
首先,進程是操作系統資源分配和調度的基本單元,它包含了程序能夠執行的必要資源。而線程也叫做輕權進程,只擁有CPU執行所需的必要資源。沒有進程,線程無法單獨執行。
其次,進程的執行一般是線程的,一條道走到黑。線程只是進程執行的不同路徑,并發的執行。
就寫這么多吧。
歡迎大家一起交流和學習啊。
-end-
新聞熱點
疑難解答