Unix實際是一種比較老的系統了,在Unix之後的操作系統的發展已經不明顯,雖然在操作系統理論上的進步也不少,但真正比較大而且應用於實際中的卻並不是很多。微內核理論可以算是一個比較實用的發展,雖然理論上微內核各個方面都有優勢,但也並不是萬用靈藥,傳統內核也有自己的優勢,尤其是近些年來,內核模塊化的發展,使得傳統內核也吸收了微內核的一些優點,反過來,Windows NT/2000的微內核,內核中包含了更多的東西,其實際大小不一定要比Unix小。
另一個非常有實際意義的操作系統發展是引入了線程概念,這也是一個目前非常基礎的概念。它也是一個非常有用的功能,能在同一個數據空間中完成多任務的並行處理,這樣幫助程序員完成多任務處理,但又不必考慮復雜的進程之間的通信問題。
在 Unix中,是使用的進程概念來區分不同的獨立計算任務,進程具有獨立的上下文空間、獨立數據空間等等特性,這樣進程就可以很容易的獨立執行,內核就可以根據優先級在進程之間進行切換,因此進程也就是最基本的內核調度實體。但是,由於計算任務的復雜性,很多任務需要使用多個進程完成,而且這些進程之間需要交換數據。為了解決這個問題,Unix中又設計了多種進程間的通信方式,稱為IPC,例如管道、共享內存、套接字等等,這些內容本身就可以獨立使用一本專門的書籍來描述了。
因此對於一些比較復雜的程序,就形成了一個怪圈,為了隔離計算任務,設計了進程的概念,為了進程之間能夠共享數據,又設計了多種 IPC通信方式。因此,人們就希望能設計一種能夠獨立執行,但沒有獨立數據空間的輕量級進程的概念,這就是線程。
明顯的,線程對於復雜系統來講非常有意義,因為不再需要復雜的 IPC通信方式維護進程之間的數據交換,同時多個線程也可以獨立、並行的執行。目前,很多數據庫系統、Java應用程序都需要線程支持。但是由於Unix系統本身並不存在線程這個概念,那麼在Unix下引入線程就有兩種比較直接的方式。
第一種方式是不在內核中實現線程,而在用戶程序本身中實現線程,這實際是對線程的一種模擬,線程之間的切換和調度是在用戶的進程內部進行的,這種方式就被稱為用戶空間的線程。這種線程的好處是實現非常簡單,而且性能也非常好,因為線程之間的切換都在用戶進程內部進行,切換開銷比較小。 FreeBSD下缺省就使用這種線程模式。
它的缺點也很明顯,首先就是不能充分利用高端服務器系統的 SMP多處理器的優點,因為一個進程只能由一個處理器處理,第二點由於用戶空間線程是在用戶空間切換,某個線程遇到一個需要阻塞的系統調用而就會造成整個進程被阻塞,因而其他線程也被阻塞,這中情況實際在線程的概念中是不允許的,但實際實現中很難被百分之百避免。
第二種實現方式是通過修改進程的實現方式來完成,可以使用不完全的進程創建方式創建共享數據空間的進程,在 Linux下這種系統調用為clone(),而在FreeBSD下它為rfork()。這種方式是Linux的基本線程處理方式,FreeBSD下可以使用linuxthread的兼容庫來實現這種線程。
用進程的方式實現的線程,能夠利用多處理器的優點,也能達到共享數據的目的,但它的線程切換開銷實際是和進程是一樣的,需要內核參與因而開銷較大。而且線程實際上是進程,在很多方面還存在問題,例如不同線程的進程標識號不一致,多線程程序的執行優先級要比單線程的要高,線程之間的同步需要比較大的開銷等等,因而也不能算理想的線程實現。
因而,雖然 FreeBSD下有兩種不同的線程實現,但它們各自都有優缺點,這就造成了多線程應用系統在FreeBSD下的表現不盡人意的現狀。
在線程方面做得比較好的操作系統有 Windows NT/2000和SUN Solaris,對於Windows NT/2000,它們本身就是以線程為基礎進行任務調度的,性能較好比較正常。SUN Solaris的線程實現則提供了另一個很好的參考平台,在Solaris中,事實上是混用了用戶空間的線程和進程基礎的線程的,使用多個進程運行更多的線程,因此可以綜合利用多處理器的優點和在進程內部切換線程的優點。
因此, FreeBSD 5.0中就希望既能利用用戶空間的線程切換開銷小的優點,又能利用內核線程支持多處理器的優點。FreeBSD 5.0在這個方向走的更遠,就是將系統內核的最基本的調度實體從進程改變為線程。簡單的講,FreeBSD 5.0進程中的多個線程按照系統的處理器數量在內核中分為相應數量的組,可以分別在多個處理器上執行,這樣就可以充分發揮多處理器的優勢。而線程之間的切換是由用戶空間來調度的,但用戶空間的線程調度程序可以和內核交互,例如當一個線程阻塞的時候,內核將通知線程調度程序啟動另一個線程,而內核進行進程調度的時候,就直接針對線程組切換到正確的線程。
雖然原理上並不復雜,但實現起來相當困難,最基本的一點就是需要將內核調度的實體從原先的進程改變為線程,這樣內核調度的時候就可以直接切換到線程隊列中的正確線程,而不是首先切換到進程,再在進程內切換到線程。這一點工作就需要將原本很多針對進程的內核設計進行改變,例如內核代碼中所有涉及進程控制塊 PCB的地方都需要改動,因為系統不再使用進程控制塊PCB來執行任務調度,而是使用線程控制塊TCB來作為最基本的調度實體。
因此,當這個工作真正完成, FreeBSD就將成為一個真正的內核級別支持多線程的系統。