內核級線程(KLT)和用戶級線程(ULT)
內核級線程(KLT)和用戶級線程(ULT)
tags: KLT ULT 內核級線程 用戶級線程
引言:本文涉及到操作系統的內核模式和用戶模式,如果不太懂的話,可以參看我的這篇文章內核模式和用戶模式,其中簡單的進行了介紹。
進程和線程
首先說一下線程對於進程的優勢,這其實就是線程出現的意義。
進程是資源擁有的基本單位,進程切換需要保存進程狀態,會造成資源的消耗。同一進程中的線程,共享進程獲取的部分資源。在同一進程中,線程的切換不會引起進程切換,線程的切換需要的資源少於進程切換,可以提高效率。
內核級線程(Kemel-Level Threads, KLT 也有叫做內核支持的線程)
- 線程管理的所有工作(創建和撤銷)由操作系統內核完成
- 操作系統內核提供一個應用程序設計接口API,供開發者使用KLT
純內核級線程特點:
- 進程中的一個線程被阻塞,內核能調度同一進程的其他線程(就緒態)占有處理器運行
- 多處理器環境中,內核能同時調度同一進程的多線程,將這些線程映射到不同的處理器核心上,提高進程的執行效率。
- 應用程序線程在用戶態運行,線程調度和管理在內核實現。線程調度時,控制權從一個線程改變到另一線程,需要模式切換,系統開銷較大。
用戶級線程(User-Level Threads ULT)
- 用戶空間運行線程庫,任何應用程序都可以通過使用線程庫被設計成多線程程序。線程庫是用於用戶級線程管理的一個例程包,它提供多線程應用程序的開發和運行支撐環境,包含:用於創建和銷毀線程的代碼、在線程間傳遞數據和消息的代碼、調度線程執行的代碼以及保存和恢復線程上下文的代碼。
- 所以線程的創建,消息傳遞,調度,保存/恢復上下文都有線程庫來完成。內核感知不到多線程的存在。內核繼續以進程為調度單位,並且給該進程指定一個執行狀態(就緒、運行、阻塞等)。
純用戶級線程的特點:
- 線程切換不需要內核模式,能節省模式切換開銷和內核資源。
- 允許進程按照特定的需要選擇不同的調度算法來調度線程。調度算法需要自己實現。
- 由於其不需要內核進行支持,所以可以跨OS運行。
- 不能利用多核處理器有點,OS調度進程,每個進程僅有一個ULT能執行
- 一個ULT阻塞,將導致整個進程的阻塞。
jacketing技術可以解決ULT一個線程阻塞導致整個進程阻塞。
jacketing的目標是把一個產生阻塞的系統調用轉化成一個非阻塞的系統調用。例如,當進程中的一個線程調用IO中斷錢,先調用一個應用級的I/O jacket例程,而不是直接調用一個系統I/O。讓這個jacket例程檢查並確定I/O設備是否忙。如果忙,則jacketing將控制權交給該進程的線程調度程序,決定該線程進入阻塞狀態並將控制權傳送給另一個線程(若無就緒態線程咋可能執行進程切換)。
線程實現的組合策略
可以看出,用戶級線程和內核級線程都有各自的優點和缺點,在應用上主要表現為:
- 用戶級多線程對於處理邏輯並行性問題有很好的效果。不擅長於解決物理並發問題。
- 內核級多線程適用於解決物理並行性問題。
組合策略:
由操作系統內核支持內核級多線程,由操作系統的程序庫來支持用戶級多線程,線程創建完全在用戶空間創建,現成的調度也在應用程序內部進行,然後把用戶級多線程映射到(或者說是綁定到)一些內核級多線程。編程人員可以針對不同的應用特點調節內核級線程的數目來達到物理並行性和邏輯並行性的最佳方案。
附上三種線程模式的圖,幫助理解(來自網絡,版權不可考,如發現出處可以聯系作者刪除或者增加版權說明)
![三種線程模式示意圖](https://images2018.cnblogs.com/blog/1356320/201804/1356320-20180402142408977-58366608.jpg)
其實這裏還有一個輕進程的概念,但是我覺得不寫在本文中反而更好理解。另外如果有什麽地方寫的不好,歡迎大家評論交流。
內核級線程(KLT)和用戶級線程(ULT)