《深入計算機系統》(第十一章)(第十二章)(第十三章)

                                第三部分:程序間的交互和通信

第十一章   系統級I/O

輸入/輸出(I/O)是主存(main   memory)和外部設備(磁盤驅動器、終端和網絡)之間拷貝數據的過程。

輸入操作是從I/O設備拷貝數據到主存,輸出則相反。

所有語言的運行時系統都提供執行I/O的較高級別的工具。高級別I/O函數工作良好,沒有必要直接使用Unix  I/O.那麼爲什麼還要麻煩地學習Unix  I/O呢?

1、瞭解Unix  I/O將幫助你理解其他的系統概念

2、有時你除了使用Unix  I/O以外別無選擇。

所有的I/O都能以一種統一且一致的方式來執行:打開文件、改變當前文件位置、讀寫文件、關閉文件

一個文本行就是一個由換行符結尾的ASCII碼字符序列。

內核用三種相關的數據結構來表示打開的文件:1、描述符表   2、文件表   3、v-node 表

I/O 重定向:Unix  shell提供了  I/O重定向操作符,允許用戶將磁盤文件盒標準輸入輸出聯繫起來。

ANSIC定義了一組高級輸入輸出函數,稱爲標準I/O庫。爲程序員們提供了Unix  I/O的較高級別的接口。

相關的流限定:1、輸入函數跟在輸出函數之後。2、輸出函數跟在輸入函數之後。

標準I/O庫是基於Unix  I/O實現的。

                  第十二章    網絡編程

每個網絡都是基於客戶端-服務器模型的。客戶端-服務器模型中的基本操作是事務。

一個客戶端-服務器事務由四部分組成:

1、當一個客戶端需要服務時,它想服務器發送一個請求。發起一個事物。

2、服務器收到請求後,解釋它,並以適當的方式操作它的資源。

3、服務器給客戶端發送一個響應,並等待下一個請求。

4、客戶端收到響應並處理它。

客戶端-服務器是進程,不是上下文中常被稱爲的機器或主機。一臺主機可以同時運行許多不同的客戶端和服務器,而且客戶端-服務器的事務可以在同一臺或不同的主機上。

客戶端和服務器通常運行在不同的主機上,並且通過計算機網絡的硬件和軟件資源來通信。對於一個主機而言,網絡又是一種I/O設備。作爲數據源和數據接收方。

多個不兼容的局域網可以通過叫做路由器的特殊計算機連接起來,組成一個internet(互聯網絡)

我們經常使用小寫細目的internet描述一般概念,而大寫字母的Internet來描述一種特殊的實際應用,也就是所謂的全球IP因特網。

每臺因特網主機都運行實現TCP/IP(傳輸控制協議/互聯網絡協議)的軟件。

TCP/IP實際是一個協議族,其中每個都提供不同的功能。

IP地址是一個32位無符號整數。

因特網客戶端和服務器互相通信時使用的是IP地址,然而,很難記,所以因特網定義了域名,以及一種將域名映射到ip地址的機制。

因特網客戶端和服務器通過在線連接上發送和接收字節流來通信,從連接一對進程的意義上而言,連接時點對點的。從數據可以同時雙向流動的角度來說,它是全雙工的。

套接字是連接的端點。每個套接字都有相應的套接字的地址,是由一個因特網地址和一個16位的整數端口組成的,用“地址:端口”來表示。

一個連接是由它兩端的套接字地址唯一確定的。這對套接字地址叫做套接字對。

套接字接口是一組用來結合Unix  I/O函數創建網絡應用的函數。

從Unix內核的角度來看,套接字就是通信的端點。從Unix程序的角度來看,套接字就是一個有相應描述符的打開文件。

客戶端是發起連接請求的主動實體。服務器是等待來自客戶端的連接請求的被動實體。

監聽描述符是作爲客戶端連接請求的一個端點。

已連接描述符是客戶端和服務器之間已經建立起來了的連接的一個端點。

Web客戶端和服務器之間的交互用的是一個基於文本的應用級協議,叫做HTTP(超文本傳輸協議)HTTP協議是個簡單的協議。一個Web客戶端(就是瀏覽器)打開一個到服務器的因特網連接,並且請求某些內容。服務器響應所請求的內容,然後關閉連接,瀏覽器讀取這些內容,並把它顯示在屏幕上。

Web服務和常規的文件檢索服務(如:FTP)的主要區別是Web內容可以用HTML來編寫。

Web服務器以兩種不同的方式向客戶端提供內容:1、取一個磁盤文件,並將它的內容返回給客戶端。磁盤文件稱爲靜態內容,而返回文件給客戶端的過程稱爲服務靜態內容。

2、運行一個可執行文件,並將它的輸出返回給客戶端。運行時可執行文件產生的輸出稱爲動態內容,而運行程序並返回它的輸出到客戶端的過程稱爲服務動態內容。

關於服務器如何解釋一個URL的後綴,由三點需要理解:

1、確定一個URL指向的是靜態內容還是動態內容沒有標準的規則。每個服務器對它所管理的文件都有自己的規則。

2、後綴中的最開始的哪個“/”不表示Unix根目錄,它表示的是被請求內容類型的主目錄。

3、最小的URL後綴是“/”字符,所有服務器將其擴展爲某個默認的主頁。

HTTP是基於在因特網連接上傳送的文本行的

一個HTTP請求的組成是這樣的,一個請求行,後面跟零個或更多個請求報頭,再跟隨一個空的文本行來終止報頭列表。

HTTP響應和HTTP請求是相似的。一個HTTP響應的組成是這樣的:一個響應行,後面跟隨着零個或更多的響應報頭,再跟隨一個終止報頭的空行,再跟隨一個響應主體。

HTTP POST請求中的參數是在請求主體中而不是URL中傳遞的。

服務器如何將其他信息傳遞給子進程:CGI定義了大量的其他環境變量,一個CGI程序在它運行時,可以設置這些環境變量。

子進程將它的輸出發送到哪裏:一個CGI程序將它動態內容發送到標準輸出。

                                        第十三章   併發編程

如果邏輯控制流在時間上重疊,那麼它們就是併發的,這種一般現象,稱爲併發性,出現在計算機許多不同的層面中。

目前爲止,我們主要將併發性看做是一種內核用來運行多個應用程序的策略。但是併發性不僅僅侷限於內核,它可以在應用程序中扮演重要角色。

應用級並行在其他情況下也有用:

1、在多處理器上進行並行計算2、訪問慢速I/O設備  3、與人交互  4、通過推遲工作以減少執行時間  5、服務多個網絡客戶端。

使用應用級併發的應用程序稱爲併發程序。現代操作系統提供了一種基本的構造併發程序的方法:1、進程(構造併發程序最簡單的方法) 2、I/O多路複用 3、線程

關於進程的優劣:對於父、子進程間共享狀態信息,進程是一個非常清晰的模型;共享文件表,但是不共享用戶地址空間。有獨立的進程地址空間既是優點也是缺點,優點:一個進程不可能不小心覆蓋另一個進程的虛擬存儲器,這就消除了許多令人迷惑的錯誤。缺點:獨立的地址空間使得進程共享狀態信息變得更加困難,爲了共享信息它們必須使用顯示的IPC機制。基於進程設計的另一個缺點是,它們往往比較慢,因爲進程控制和IPC的開銷很高。

I/O多線路技術可以用作併發事件驅動程序的基礎,在事件驅動中流是作爲某種事件的結果前進的。

I/O多線路複用技術的優劣:

優點:1、它比基於進程的設計給了程序員更多的對程序行爲的控制。

   2、一個基於I/O多路複用的事件驅動器是運行在單一進程上下文中,因此每個邏輯流都能訪問該進程的全部地址空間

缺點是編碼複雜。

一個線程就是運行在一個進程上下文中的一個邏輯流。

在任何一個時間點上,線程是可結合的或者是分離的。一個可結合的線程能夠被其他線程收回其資源和殺死。在被其他線程收回之前它是不釋放的。相反,一個分離的線程是不能被其他線程回收或殺死的,它的存儲器資源在它終止時由系統自動釋放。

從程序員的角度來看,線程很有吸引力的一個方面就是多個線程很容易共享相同的程序變量。然而這種共享很棘手的,爲了編寫正確的多線程程序,我們必須對所謂的共享以及它是如何工作的有很清楚的瞭解。

線程存儲器模型:一組併發線程運行在一個進程的上下文中,每個線程都有它自己獨立的線程上下文,包括現場呢過ID、棧、棧指針、程序計數器、條件代碼和通用目的的寄存器值。每個線程和其他線程一起共享進程上下文的剩餘部分。這包括整個用戶虛擬地址空間,它是由只讀文本(代碼)、讀/寫數據、堆以及所有的共享庫代碼和數據區域組成的。線程也共享同樣的打開文件的集合。

從實際操作的角度來說,讓一個線程去讀或寫另一個線程呢過的寄存器值是不可能的。另一方面,任何線程都可以訪問共享虛擬存儲器的任意位置。如果某個線程修改了一個存儲器位置,那麼其他每個線程最終都能在它讀這個位置時發現這個變化。因此寄存器是不共享的,而虛擬存儲器總是共享的。

各自獨立的線程棧的存儲器模型不是那麼整齊清楚的。這些棧被保存在虛擬地址空間的棧區域中,並且通常它們相應的線程獨立第訪問。說是通常不是總是,因爲不同的線程棧是不對其他線程設防的。所以,如果一個線程不知何故得到一個指向其他線程棧的指針,那麼它就可以讀這個棧的任何部分。

將變量映射到存儲器。多線程的C程序中的變量根據它們存儲類型被映射到虛擬存儲器。1、全局變量。定義在函數之外的變量  2、本地自動變量。  3、本地靜態變量

進度圖:一個進度圖將n個併發線程的執行模型化爲一條n維笛卡爾空間中的軌跡。

一個進度圖將指令執行模型化爲一個從一種狀態到另一種狀態的轉換。一個轉換被表示爲一條從一個點到相鄰點的有向邊,合法的轉換時向右或者向上。兩個指令不能再同一時刻完成——對角線轉換時不允許的,程序覺不會反響運行,所以向下或向左的運行時不合法的。

進度圖給了我們一種較好的方法,將在單處理器上的併發程序執行可視化。不過它的確也有侷限性,特別是對於在多處理器上的併發執行,多處理器的工作方式是進度圖不能解釋的。

信號量提供對共享變量的互斥訪問、調度對共享資源的訪問。

有一類重要的線程安全函數,叫做可重入函數,其特點在於它們具有這樣一種屬性:當它們被多個線程調用時,不會引起任何共享數據。

競爭:當一個程序的正確性依賴於一個線程要在另一個程序到達y點之前到達它的控制流中的x點時。就會發生競爭。

死鎖:信號量引入了一種潛在的令人厭惡的運行時錯誤,叫做死鎖,它指的是一組線程被阻塞了,等待一個永遠也不會爲真的條件。進程圖對於理解死鎖是一個無價的工具。

程序員應該總是檢查系統級函數返回的錯誤代碼。有許多細微方式導致錯誤的出現,只有使用內核能夠提供給我們的狀態信息才能理解爲什麼有這樣的錯誤。











































發佈了49 篇原創文章 · 獲贊 3 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章