應用2.6內核超線程模式
對於大多數應用軟件開發者來說,Linux 2.4和2.6內核家族間的大部分差異對它們沒有直接的影響。大多數內核變化只是為了提高系統性能而已。但也有例外,對某些應用軟件而言,內核和系統的變化對它們的推廣和它們對其它進程和線程的管理都具有一定的影響。
2.6內核為用戶帶來了一種新的、改進的超線程模式。這種模式是通過NPTL(Native POSIX Thread Library)實施的。新的超線程模式的采用對於開發人員、系統運行時間庫(如GNU C庫)、共享應用軟件庫等有著非凡的意義。本文將介紹基本的超線程概念,討論已有的Linux超線程模式,並著重指出在2.6內核下如何修改已有多線程應用軟件。
超線程技術
在Linux之類的多進程操作系統中,一個進程生成另一個進程是最基本的概念。最典型的例子是外殼程序,如Bash外殼程序。它是一個標准的Linux命令翻譯程序。外殼程序根據用戶的命令執行相應的應用程序,可以直接啟動多個命令並等待它們完成,也可以將多個命令分開同時執行。
一個進程通常可以通過一組fork()和exec()函數調用來生成新的進程。初始進程調用fork()函數,產生一個子進程。子進程繼承了母進程的整個執行環境。fork()函數調用將子進程的進程標識(PID)反饋給母進程,同時還包括子進程中的PID.然後,子進程使用exec()函數調用來執行其它的命令,改變繼承來的執行環境。同時,母進程或者迅速退出,或者等待子進程回到其初始狀態。
Linux超線程模式
Linux 2.6內核以前所有版本的標准Linux超線程庫被稱為LinuxThreads.這種庫可以與不低於GLIBC 2.0版本GNU C庫一起工作,並且與POSIX兼容。
在LinuxThreads和Native POSIX Thread Library(NPTL)源代碼的編譯過程中,產生的主要庫是libpthread.so和libpthread.a.為此,LinuxThreads和pthreads名稱過去可以互換使用。但是引入NPTL後,兩者極易發生混淆。本文使用LinuxThreads和NPTL以便明確區分兩個超線程庫和它們的功能。
LinuxThreads擁有不同的性能、可伸縮性和可用性限制。LinuxThreads針對單一進程可產生的線程數通過一個編譯器設置。此外,它還使用一個進程管理器協調每個進程產生的所有線程間的關系。這樣會大大增加線程建立和消除占用的資源。盡管基本上每個線程都有獨立的進程ID,但信號的處理仍是在各個進程中完成的。由於種種原因,在LinuxThreads實施過程中,同時產生並工作的線程數量常常會受到限制。這些原因包括內核與用戶空間線程間的不對稱關系,缺少線程間通信和分享資源所需的線程同步原語等。
Linux的另一超線程模式是IBM公司的下一代POSIX線程(NGPT)項目。它是一個與LinuxThreads套件一起工作的外部超線程庫。但是它可以提供額外的POSIX支持和優於標准LinuxThreads套件的性能。NGPT套件可用於Linux2.4和更早的內核,由於新超線程模式的產生,其應用范圍越來越小。
NPTL自從出現2.5內核後便開始逐漸代替LinuxThreads和NGPT.NPTL為Linux系統提供更高性能的超線程支持,並且可提供多線程企業應用軟件所需的基本功能,此外還可提供高容量、高加載量的網絡和郵件服務器等。NPTL的開發是2.5內核開發進程的一部分,並且與Linux運行時元件(如GLIBC)集成在一起,具備了眾多優勢的NPTL是未來Linux線程的發展方向。
一些Linux系統生產商(如Red Hat公司)已開始向舊版本內核追加NPTL,甚至通過一個環境變量為特定的可選進程創建超線程環境。在支持此功能的系統中,變量可以通過下面的命令來設置:
# eXPort LD_ASSUME_KERNEL=2.4.1
對於那些原本依靠LinuxThreads模式的已有應用軟件來說,要想繼續在NPTL環境下工作,這是一個比較聰明的辦法,但同時也是一個權宜之計。為了能更好的利用NPTL的設計和性能優勢,用戶需要對使用超線程模式的現有應用軟件的代碼進行升級。
應用軟件的重編譯
盡管有許多應用軟件從2.4內核到2.6內核移植過程中不需要重新編譯,但是大多數多線程應用軟件的NPTL附加技術需要進行略微的修改。
那些需要重新編譯的應用軟件也許會受到升級編譯程序的影響。這些編譯程序一般都包含在基於2.6內核的Linux套件中,例如TimeSys Linux系統。TimeSys在推出2.6 Reference Distributions的同時捆綁了GCC的3.3.2版本的C和C++編譯程序,並使用升級版本的binutils套件彌補標准Linux工具鏈的不足。
使用基於2.6的內核並不意味著用戶已自動使用NPTL。為了決定系統使用的超線程庫,用戶可以執行下面的命令,對GNU_LIBPTHREAD_VERSION環境變量進行檢測,如下所示:
# getconf GNU_LIBPTHREAD_VERSIONlinuxthreads-0.10 If your system uses the NPTL, the command would return the value of NPTL that your system was using,as in the following example: # getconf GNU_LIBPTHREAD_VERSIONnptl-0.60
如果用戶正在建立適用於2.6內核的工具鏈,那麼必須確定已經在2.6內核上建立了擁有NPTL技術支持的“工具鏈”。此外,用戶還需要較新的C語言庫源代碼。例如,如果用戶正在建立擁有NPTL支持的GBLIC,那麼就要使用2.3.3版本以上的GBLIC源代碼。為GBLIC提供NPTL支持的過程與提供LinuxThreads支持的過程十分相似。不同的是在設置GBLIC時,使用“--enable-add-ons=nptl”設置選項,而不是“--enable-add-ons=linuxthreads”。用戶還需要一個新版本的GCC(3.3.2或更高版本)和支持框架信息調用(CFI)指令的binutils(2.14.90.0.7或更高版本)。
一般情況下,如果用戶的應用軟件使用較早版本的GCC進行編譯,用戶也許會注意到報警信息、源代碼尺寸等不同之處。此外,GCC編譯程序和剩余工具鏈提供的選項也不盡相同。當用戶在對嵌入式應用軟件進行重新編譯時,必須了解代碼尺寸有增大的潛在趨勢。用戶也許需要充分利用額外或新的優化選項,以便在資源有限的環境下,繼續適應現有的應用軟件。版本越新的GCC越能適應各種C或C++規格,並提高了對應用軟件代碼的要求。一般情況下,從升級編譯程序中獲得的新報警信息對消除潛在缺陷是十分有用的。
為NPTL升級應用軟件
2.4內核的超線程支持和NPTL支持間的變化為設計和性能的提高提供了廣闊的改進空間。在2.4內核下,NPTL與POSIX規格的適應程度要比與LinuxThreads套件的適應程序高得多。NPTL還支持諸如mutexes之類的功能。最後,NPTL要比2.4內核的超線程支持更有效。
在向NPTL移植過程中,用戶需要對應用軟件邏輯作更復雜的修改。這些修改與NPTL對POSIX信號和信號處理的支持有關。LinuxThreads實施一般性的Unix型線程,但是它卻受各種實施細節的限制。因為NPTL是一種與POSIX相適應的超線程實施方案,所以它在進程間信號處理和線程間信號處理方面表現得較為優秀。在NPTL中,信號可以由一個線程傳給另一線程,而不只是進程間的傳遞。信號也可以使用參數來完成線程間的信息傳遞。
在使用NPTL時,用戶還需要對識別具體線程的現有代碼進行修改。在LinuxThreads下,每個線程都擁有惟一的進程ID(PID)。而現在,母進程下的各個線程都共享同一PID,因此getpid()函數將為進程中的所有線程返回同一PID。在NPTL下,一個線程的線程ID在使用時必須是唯一的,這樣才能對每個線程進行正確的識別。
對線程ID和進程ID進行的修改還意味著進程產生的方式現在需要針對線程而進行。例如,exec()函數目前可以對線程進行操作,因此一個線程可以繼承調用者的PID。只有當整個進程結束時,多線程進程的母進程才知道某一子進程已經執行完畢。有關線程的變化還會對相關fork()調用產生影響。例如,在pthread_at_fork()函數中登記的函數在vfork()發生時將無法再繼續運行。
除了對線程識別的內部構件進行修改外,NPTL廢除了LinuxThreads的管理者線程的概念,簡化了進程和線程間的關系。這些也許需要對應用軟件做適當的修改。
最後,使用新超線程庫意味著在LinuxThreads可以使用的一些超線程函數在NPTL下將無法繼續使用。例如pthread_kill_other_threads_np()函數便無法繼續使用。該函數將的作用是激活與POSIX相適應的exec()函數,而在NPTL下,exec()函數無法再與POSIX相適應。
總結
修改計算機運行的內核並不是件容易的事,但是它也不是不可能完成的任務。以上五篇文章中,我們著重介紹了2.6內核設置中遇到的主要問題、升級硬件驅動程序、移植桌面和定制系統以及升級應用軟件。TimeSys公司的2.6 Reference Distribution是第一款應用於PPC系統的Linux套件。諸如TimeSys公司的TimeStorm IDE和TimeStorm Linux系統開發套件(LDS)之類的高質量商業軟件可以幫助我們移植所有的Linux內核、硬件驅動程序、應用軟件。此外,它們還可以幫助我們對系統進行配置,以便充分發揮2.6內核、升級套件、穿線技術等軟件技術的作用。
Linux作為開放系統運動中最耀眼的明星,積極投身於軟件產業的變革。Linux內核作為所有Linux系統的核心,在發展過程中不斷地引入新技術,改善性能、可伸縮性、技術支持和可用性。2.6內核拓展了Linux系統的應用范圍,從PDA、進程控制系統、機頂盒到企業服務器處處都能看到它的身影。Linux系統的成本、動力和技術支持優勢在今天的商業市場和飛速發展的技術環境中顯得更加明顯。