前言
一個進程內有多個線程,線程有自己的寄存器,程序計數器,堆棧,狀態。但是線程間是沒有保護的,可以共享地址空間,打開文件集,子進程,定時器以及相關信號量。為什么沒有保護,原因是:不可能,也沒必要。不同進程可能來自不同用戶,它們之間彼此可能有敵意,用戶所持有的資源以進程為單位。
與傳統進程一樣,線程也擁有運行,阻塞,就緒終止狀態,正在運行的線程獨占CPU并且活躍。與進程狀態切換一致,這里就不介紹了。
每個線程堆棧都有一幀,在該棧幀存放了局部變量和過程調用后的返回地址。
在多線程情況下,進程通常會從當前的單個線程開始,也就是主線程,該線程會調用庫函數(thread_create)來創建新線程。一般來說,線程之間是平等的。這里介紹其它庫函數:
pthread_exit:線程運行結束時,退出,線程消失。
pthread_join:一個線程可以阻塞等待另一個線程退出。
pthread_yield:允許線程自動放棄CPU讓給其它線程。
4. pthread_attr_init:創建并初始化一個線程的屬性結構。
5. pthread_attr_destroy:刪除一個線程的屬性結構。
pthread.h
在用戶態實現線程
在用戶空間管理線程時,每個進程都會有一個線程表,用來跟蹤該進程中的線程。這些表和內核空間中的進程表相似,不過它僅記錄線程的屬性。
用戶線程中,每個進程都有其相關調度算法,可擴展性高,這是因為內核線程需要固定的表格和堆棧空間。
但是,由于用戶線程沒有時鐘中斷,導致某線程想要運行時,只能依靠前一個線程主動放棄CPU,所以沒有輪轉的說法。
在內核中使用線程
當內核支持管理線程時,進程中就沒有線程表了,相反,在內核中就有一張線程表,線程想要創建新線程時,通過系統調用來對線程表更新。另外,內核還維護了傳統的進程表。
在上述情況下,當一個線程阻塞時,就可以通過系統調用(內核中的線程表)來切換線程了。
在內核回收和創建線程代價是比較大的,所以回收時,一般會將線程標記為不可運行(并不是真正的回收),需要時再啟動。用戶態線程不需要。
雖然內核線程可以解決很多問題,但不是能解決所有問題。比如信號問題,創建新進程問題等......
混合實現
人們研究出了采用多個用戶線程對應一個內核線程的方法,多個用戶線程多路復用。
彈出式線程
在分布式系統中,線程經常使用,通常下,服務接受到消息后,該服務所對應的線程會阻塞并receive,但是彈出式線程會創建一個新的線程去處理收到的消息。
在一些OS中,協作的進程可能共享一些彼此都能讀寫的公共存儲區。該存儲區可能是一個數據結構,可能是一個共享文件。
審核編輯:劉清
-
寄存器
+關注
關注
31文章
5430瀏覽量
123989 -
計數器
+關注
關注
32文章
2290瀏覽量
96245 -
定時器
+關注
關注
23文章
3297瀏覽量
117634
發布評論請先 登錄
請問CPU與寄存器,內核態與用戶態及如何切換?
OpenHarmony喂狗源碼解讀之用戶態源碼
鴻蒙內核實現用戶態快速互斥鎖Futex設計資料合集
基于Windows 操作系統內核驅動的多核CPU 線程管理

一個內核態Key-Value存儲系統

評論