線程:**是操作系統能夠進行運算調度的最小單位。**它被包含在進程之中,是進程中的實際運作單位。一條線程指的是進程中一個單一順序的控制流,一個進程中可以併發多個線程,每條線程並行執行不同的任務。
在一個程序裏的一個執行路徑就叫做線程。線程是一個進程內部的控制序列。一切進程至少有一個執行線程。線程在進程內部運行,本質是進程地址空間內運行。在Linux系統中,在cpu眼裏,看到的PCB都有比傳統的進程更加輕量化。
通過進程虛擬地址空間,可以看到進程大部分資源,將進程資源合理分配給每個執行流,就形成了線程執行流。
線程爲了讓程序更能充分利用多核cpu資源。
創建一個新的進程,相當於開了一個新的廠子,成本比較高。(增加健壯性)。
創建一個新的線程,相當於在原廠子的基礎上新增了一條生產線,成本比較低。
每次創建一個新的進程,就會分配一個新的虛擬地址空間(複製pcb)
每次創建一個新的線程,線程共用原來的虛擬地址空間。
線程是運行在進程之中的,一個進程包含着若干個線程。
線程進程都是pcb表示的,一個pcb表示線程也表示進程。
進程:資源的管理(管理內存,管理打開的文件…)
線程:調度和執行(和進程類似,也是搶佔式的調度)
透過進程虛擬地址空間,就可以看到進程的大部分資源,將進程資源合理分配給每個執行流,就形成了線程執行流。
線程的優點
- 創建一個新的線程的代價要比創建一個新的進程小的多(虛擬地址空間不用複製)
- 與進程之間的切換相比,線程之間的切換需要操作系統做的工作要少很多
- 線程佔用的資源比進程少很多
- 能充分利用多處理器的可並行數量
- 在等待慢速I/O操作結束的同時,程序可執行其他的計算任務
- 計算密集型應用,爲了能在多個處理器系統上運行,將計算分解到多個線程中實現。
- I/O密集型應用,爲了提高性能,將I/O操作重置。線程可以同時等待不同I/O操作。
線程相比於進程的優點
- 創建和銷燬開銷更小
- 切換調度的開銷更小
- 線程佔用的資源更小
多線程/多進程的應用場景
cpu密集型:while(1)
IO密集型:1.通過網絡進行輸入輸出 2.響應UI界面(界面顯示和數據計算要多線程完成,放在由於數據計算太久導致界面卡死)
線程缺點
- 性能損失:一個很少被外部事件阻塞的計算密集型線程往往無法與共它線程共享同一個處理器。如果計算密集型線程的數量比可用的處理器多,那麼可能會有較大的損失,這裏的性能損失指的是增加了額外的同步和調度開銷,而可用的資源不變。
- 健壯性降低:編寫多線程需要更全面更深入的考慮,在一個多線程程序裏,因時間分配上的細微偏差或者因共享了不該共享的變量而造成了不良影響的可能性是很大的,換句話說線程之間是缺乏保護的。一個線程異常終止會導致進程異常終止。
- 缺乏訪問控制:進程是訪問控制的基本粒度,在一個線程中調度某些OS函數會對整個進程造成影響。
- 編程難度提高:編寫與調試一個多線程程序比單線程程序困難的多。對線程的可靠性要求更高。線程安全
線程之間共用的資源:
- 虛擬地址空間。
- 文件描述符表
線程之間不共用的資源: 不共用不是私有
- 棧(函數調用棧就是平時說的棧,局部變量)
- 上下文信息(CPU中寄存器的信息)
- errno錯誤碼,每個線程有自己單獨的errno錯誤碼
線程不是越多越好,達到一定數目的時候效率就沒法提升了。
線程如果多了,多個線程嘗試訪問同一個資源,就會打架(互斥)。
某個線程可能一直得不到執行的機會,線程飢餓(同步)。
如果某個進程異常終止,整個進程都異常終止了。