線程概念
什么是線程
- 在一個程序里的一個執行路線就叫做線程(thread)。
- 更準確的定義是:線程是“一個進程內部的控制序列” 一切進程至少都有一個執行線程
- 線程在進程內部運行,本質是在進程地址空間內運行
- 在Linux系統中,在CPU眼中,看到的PCB都要比傳統的進程更加輕量化
- 透過進程虛擬地址空間,可以看到進程的大部分資源,將進程資源合理分配給每個執行流,就形成了線程 執行流
LWP:light weight process 輕量級進程
- 進程:獨立地址空間,擁有 PCB
- 線程:也有 PCB,但沒有獨立的地址空間(共享) 區別:在于是否共享地址空間。
獨居(進程);合租(線程)。
Linux 下:
線程:最小的執行單位
進程:最小分配資源單位,可看成是只有一個線程的進程。
一個進程創建多少個線程,他們都共用一塊地址空間,但是線程越多,占用cpu越多,也就是cpu分的時間片越多,效率越高。因為線程是最小的執行單位,要被執行,必須要用cpu。
Linux內核線程實現原理
類 Unix 系統中,早期是沒有“線程”概念的,80 年代才引入,借助進程機制實現出了線程的概念。因此在這 類系統中,進程和線程關系密切。
- 輕量級進程(light-weightprocess),也有 PCB,創建線程使用的底層函數和進程一樣,都是 clone
- 從內核里看進程和線程是一樣的,都有各自不同的 PCB,但是 PCB 中指向內存資源的三級頁表是相同的
- 進程可以蛻變成線程
- 線程可看做寄存器和棧的集合
- 在 linux 下,線程最是小的執行單位;進程是最小的分配資源單位
線程1和線程2程序內部執行的函數不會一樣,所以對應的棧不一樣。
Linux操作系統中cpu劃分時間輪片的依據
查看 LWP 號:ps –Lf pid
** 查看指定線程的 lwp 號。不是線程ID**
注意
- 對于進程來說,相同的地址(同一個虛擬地址)在不同的進程中,反復使用而不沖突。原因是他們雖虛擬地址一樣,
- 進程的頁目錄、頁表、物理頁面各不相同。相同的虛擬地址,映射到不同的物理頁面內存單元,最終訪問不同的物理頁 面。
- 線程不同。兩個線程具有各自獨立的 PCB,但共享同一個頁目錄,也就共享同一個頁表和物理頁面。所以 兩個 PCB 共享一個地址空間。 實際上,無論是創建進程的 fork,還是創建線程的 pthread_create,底層實現都是調用同一個內核函數 clone。
如果復制對方的地址空間,那么就產出一個“進程”;如果共享對方的地址空間,就產生一個“線程”。 - 因此:Linux 內核是不區分進程和線程的。只在用戶層面上進行區分。所以,線程所有操作函數 pthread_ 是 庫函數,而非系統調用。*
線程共享資源
- 文件描述符表
- 每種信號的處理方式
- 當前工作目錄
- 用戶 ID 和組 ID
- 內存地址空間 (.text/.data/.bss/heap/共享庫)沒有stack
線程非共享資源
- 線程 id
- 處理器現場和棧指針(內核棧)
- 獨立的棧空間(用戶空間棧)
- errno 變量
- 信號屏蔽字
- 調度優先級
線程優、缺點
優點:
- 提高程序并發性
- 開銷小
- 數據通信、共享數據方便
- 創建一個新線程的代價要比創建一個新進程小得多
- 與進程之間的切換相比,線程之間的切換需要操作系統做的工作要少很多
- 線程占用的資源要比進程少很多
- 能充分利用多處理器的可并行數量
- 在等待慢速I/O操作結束的同時,程序可執行其他的計算任務
- 計算密集型應用,為了能在多處理器系統上運行,將計算分解到多個線程中實現
- I/O密集型應用,為了提高性能,將I/O操作重疊。線程可以同時等待不同的I/O操作。
缺點:
- 庫函數,不穩定 ,進程中時庫函數
- 調試、編寫困難、gdb 不支持
- 對信號支持不好 優點相對突出,缺點均不是硬傷。
- 線程間缺乏訪問控制,編碼難度更高
- 線程健壯性更低
Linux 下由于實現方法導致進程、線程差別不是很大。