GB | BIG5
|
| 首頁 > 編程技術 > C/C++ > 正文 |
 |
| Solaris2.4 多線程編程指南1--線程基礎 |
| 本文出自:BBS水木清華站 作者:Mccartney (coolcat) (2002-01-29 20:25:25) |
1線程基礎 multithreading可以被翻譯成多線程控制。與傳統的UNIX不同,一個傳統 的UNIX進程包含一個單線程,而多線程(MT)則把一個進程分成很多可執行線 程,每一個線程都獨立運行。 閱讀本章可以讓你理解: Defining Multithreading Terms Benefiting From Multithreading Looking At Multithreading Structure Meeting Multithreading Standards 因為多線程可以獨立運行,用多線程編程可以 1) 提高應用程序響應; 2) 使多CPU系統更加有效; 3) 改善程序結構; 4) 佔用更少的系統資源; 5) 改善性能; 1.1定義多線程術語: 線程:在進程的內部執行的指令序列; 單線程:單線程; 多線程:多線程; 用戶級線程:在用戶空間內的由線程函數庫進程控制的現成; 輕進程:又稱LWP,內核內部的執行核代碼和系統調用的線程; 綁定(bound)線程:永遠限制在LWP內的線程; 非綁定(unbound)線程:在LWP動態捆綁和卸綁的線程; 記數信號量:一個基內存的同步機制; 1.1.1定義同時(concurrency)和並行(parallism): 在進程內至少同時有兩個線程進行(process)時存在同時性問題;至少同時有兩個線程在執行時存在並行問題; 在單處理器上執行的多線程的進程內部,處理器可以在線程中間切換執行, 這樣實現了同時執行;在共享內存多處理器上執行的同一個多線程進程,每一 個線程可以分別在不同的處理器上進行,是為並行。 當進程裡的線程數不多處理器的數量時,線程支持系統和操作系統保 証線程在不同的處理器上執行。例如在一個m處理器和m線程運行一個矩陣乘法, 每一個線程計算一列。 1.2多線程的益處 1.2.1提高應用程序響應 任何一個包含很多互不關聯的操作(activity)的程序都可以被重新設計, 使得每一個操作成為一個線程。例如,在一個GUI(圖形用戶界面)內執行一 個操作的同時啟動另外一個,就可以用多線程改善性能。 1.2.2使多處理器效率更高 典型情況下,有同時性需求的多線程應用程序不需要考慮處理器的數量。應用程序的性能在被多處理器改善的同時對用戶是透明的。 數學計算和有高度並發性需求的應用程序,比如矩陣乘法,在多處理器平台上可以用多線程來提高速度。 1.2.3改善程序結構 許多應用程序可以從一個單一的、巨大的線程改造成一些獨立或半獨立的 執行部分,從而得到更有效的運行。多線程程序比單線程程序更能適應用戶需 求的變更。 1.2.4佔用較少的系統資源 應用程序可以通過使用兩個或更多的進程共享內存的辦法來實現多一個 現成的控制。然而,每一個進程都要有一個完整的地址空間和操作系統狀態表 項。用創建和維護多進程大量的狀態表的開銷與多線程方法相比,在時間上 和空間上都更為昂貴。而且,進程所固有的獨立性使得程序員花費很多精力來 實現進程間的通信和同步。 1.2.5把線程和RPC結合起來 把多線程和RPC(remote procedure call,遠程過程調用)結合起來,你可以使用沒內存共享的多處理器(比方說一個工作站組)。這種結構把這組工作站當作一個大的多處理器系統,使應用程序分布得更加容易。 例如,一個線程可以創建子線程,每一個子進程可以做RPC,調用另外一 台機器上的過程。盡管最早的線程僅僅創建一些並行的線程,這種並行可以包 括多台機器的運行。 1.2.6提高性能 本部分的性能數據是從SPARC station2(Sun 4/75)上採集的。測量精度為微秒。 1. 線程創建時間 表1-1顯示了使用thread package做緩存的缺省堆棧來創建線程的時 間。時間的測量僅僅包括實際的生成時間。不包括切換到線程的時間。比 率(ratio)列給出了該行生成時間與前一行的比。 數據表明,線程是更加經濟的。創建一個新進程大概是創建一個 unbound線程的30倍,是創建一個包含線程和LWP的bound線程的5倍。 Table 1-1 Thread Creation Times Operation Microseconds Ritio Create unbound thread 52 - Create bound thread 350 6.7 Fork() 1700 32.7 2. 線程同步(synchronization)時間 表1-2列出了兩個線程使用pv操作的同步時間。 Table 1-2 Thread Synchronization Times Operation Microseconds Ratio Unbound thread 66 - Bound thread 390 5.9 Between Processes 200 3 1.3多線程結構一覽 傳統的UNIX支持現成概念--每一個進程包含一個單線程,所以用多進程就 是使用多線程。但是一個進程還有一個地址空間,創建一個新進程意味著需要 創建一個新的地址空間。 因此,創建一個進程是昂貴的,而在一個已經存在的進程內部創建線程是 廉價的。創建一個線程的時間比創建一個進程的時間要少成千倍,部分是因為 在線程間切換不涉及地址空間的切換。 在進程內部的線程間通信很簡單,因為線程們共享所有的東西--特別是地址空間。所以被一個線程生成的數據可以立刻提供給其他線程。 支持多線程的接口(界面)是通過一個函數庫libthread實現的。多線程通過把內核級資源和用戶級資源獨立開來提供了更多的靈活性。 1.3.1用戶級線程 線程僅僅在進程內部是可見的,在進程內部它們共享諸如地址空間、已經 打開的文件等所有資源。以下的狀態是線程私有的,即每一個線程的下列狀態 在進程內部是唯一的。 .線程號(Thread ID) .寄存器狀態(包括程序計數器和堆棧指針) .堆棧 .信號掩碼(Signal mask) .優先級(Priority) .線程私有的存儲段(Thread-private storage) 因為線程共享進程的執行代碼和大部分數據,共享數據被一個線程修改之 可以進程內的其他線程見到。當一個進程內部線程與其他線程通信的時候, 可以不經過操作系統。 線程是多線程編程的主要主要借口。用戶級的線程可以在用戶空間操作, 從而避免了與內核之間的互相切換。一個應用程序可以擁有幾千個線程而不佔 用太多的內核資源。佔用內核資源的多少主要決定應用程序本身。 在缺省情況下,線程是非常輕便的。但是,為了控制一個線程(例如,更 多地控制進程調度策略),應用程序應當綁定線程。當一個應用程序把線程的所 有執行資源綁定,線程就變成了內核資源(參見第9頁"bound 線程")。 總之,solaris用戶級線程是: .創建的低開銷,因為只在運行是佔用用戶地址空間的虛擬內存的幾個bit。 .快速同步,因為同步是在用戶級進行,不需要接觸到內核級。 .可以通過線程庫libthread很容易地實現。 圖1-1 多線程系統結構(略) 1.3.2輕進程(Lightweight Porcesses:LWP) 線程庫採用內核支持的稱為輕進程的底層控制線程。你可以把LWP看作一個 可以執行代碼和系統調用的虛擬的CPU。 大多數程序員使用線程是並不意識到LWP的存在。下面的內容僅僅幫助理解 bound和unbound線程之間的區別。 ------------------------------------ NOTE:Solaris2.x的LWP不同SunOs4.0的LWP庫,者在solaris2.x中不再被支持。 ------------------------------------ 類似在stdio中fopen和fread調用open和read,線程接口調用LWP接口, 原因是一樣的。 LWP建立了從用戶級到內核級的橋樑。每個進程包含了一個或更多LWP,每個 LWP運行著一個或多個用戶線程。創建一個現成通常只是建立一個用戶環境 (context),而不是創建一個LWP。 在程序員和操作系統的精心設計下,用戶級線程庫保証了可用的LWP足夠驅動 當前活動的用戶級線程。但是,用戶線程和LWP之間不是一一對應的關系,用戶級 線程可以在LWP之間自由切換。 程序員告訴線程庫有多少線程可以同時"運行"。例如,如果程序員指定最多有 三個線程可以同時運行,至少要有3個可用的LWP。如果有三個可用的處理器,線程 將並行進行。如果這裡只有一個處理器,操作系統將在一個處理器上運行三個LWP。 如果所有的LWP阻塞,線程庫將在緩沖池內增加一個LWP。 當一個用戶線程由同步原因而阻塞,它的LWP將移交給下一個可運行的線程。 這種移交是通過過程間的連接(coroutine linkage),而不是做系統調用而完成。 操作系統決定哪一個LWP什時候在哪一個處理器上運行。它不考慮進程中線 程的類型和數量。內核按照LWP的類型和優先級來分配CPU資源。線程庫按照相同 的方法來為線程分配LWP。每個LWP被內核獨立地分發,執行獨立的系統調用,引 起獨立的頁錯誤,而且在多處理器的情況下將並行執行。 一些特殊類型的LWP可以不被直接交給線程。(!?不明) 1.3.3非綁定線程Unbound Threads 在LWP緩沖池中排隊的線程稱為unbound thread。通常情況下我們的線程都是 unbound的,這樣他們可以在LWP之間自由切換。 線程庫在需要的時候激活LWP並把它們交給可以執行的線程。LWP管理線程的 狀態,執行線程的指令。如果線程在同步機制中被阻塞,或者其他線程需要運行, 線程狀態被存在進程內存中,LWP被移交給其他線程。 1.3.4綁定線程Bound Threads 如果需要,你可以將一個線程綁定在某個LWP上。 例如,你可以通過綁定一個線程來實現: 1. 將線程全局調度(例如實時) 2. 使線程擁有可變的信號棧 3. 給線程分配獨立的定時器和信號(alarm) 在線程數多LWP時,bounded比unbound線程體現出一些優越性。 例如,一個並行的矩陣計算程序在每個線程當中計算每一行。如果每個處理器 都有一個LWP,但每個LWP都要處理多線程,每個處理器將要花費相當的時間來切換 線程。在這種情況下,最好使每個LWP處理一個線程,減少線程數,從而減少線程 切換。 在一些應用程序中,混合使用bound和unbound線程更加合適。 例如,有一個實時的應用程序,希望某些線程擁有全局性的優先級,並被實時 調度,其他線程則轉入台計算。另一個例子是窗口系統,大多數操作都是 unbound的,但鼠標操作需要佔用一個高優先級的,bound的,實時的線程。 1.4多線程的標準 多線程編程的歷史可以回溯到二十世紀60年代。在UNIX操作系統中的發展是從 80年代中期開始的。也許是令人吃驚的,關支持多線程有很好的協議,但是今 天我們仍然可以看到不同的多線程開發包,他們擁有不同的接口。 但是,某幾年裡一個叫做POSIX1003.4a的小組研究多線程編程標準。當標準完 成,大多數支持多線程的系統都支持POSIX接口。很好的改善了多線程編程的可 移植性。 solaris多線程支持和POSIX1003.4a沒有什根本性的區別。雖然接口是不同 的,但每個系統都可以容易地實現另外一個系統可以實現的任何功能。它們之間沒 有兼容性問題,至少solaris支持兩種接口。即使是在同一個應用程序裡,你也可 以混合使用它們。 用solaris線程的另一個原因是使用支持它的工具包,例如多線程調試工具 (multighreaded debugger)和truss(可以跟蹤一個程序的系統調用和信號), 可以很好地報告線程的狀態。
(http://www.fanqiang.com)
進入【UNIX論壇】
|
|
| 相關文章 |
Solaris2.4 多線程編程指南7--編程指南 (2002-01-29 20:33:46) Solaris2.4 多線程編程指南6--編譯和調試 (2002-01-29 20:32:52) Solaris2.4 多線程編程指南5--安全和不安全的接口函數 (2002-01-29 20:32:05) Solaris2.4 多線程編程指南4--操作系統編程 (2002-01-29 20:29:36) Solaris2.4 多線程編程指南3--使用同步對象編程 (2002-01-29 20:28:07) Solaris2.4 多線程編程指南2--用多線程編程 (2002-01-29 20:26:32) Solaris2.4 多線程編程指南1--線程基礎 (2002-01-29 20:25:25) Linux下的多線程編程 (2001-08-11 09:05:00)
|
|
|
|
 |
★ 樊強制作 歡迎分享 ★ |