程序員必讀經(jīng)典UNIX操作系統(tǒng)設(shè)計(jì)》與您相約在6月

      網(wǎng)友投稿 792 2025-03-31

      ###主要目錄結(jié)構(gòu): 第1章 系統(tǒng)概貌

      第2章 內(nèi)核導(dǎo)言

      第3章 數(shù)據(jù)緩沖區(qū)高速緩沖

      第4章 文件的內(nèi)部表示 第5章 文件系統(tǒng)的系統(tǒng)調(diào)用 第6章 進(jìn)程結(jié)構(gòu) 第7章 進(jìn)程控制 第8章 進(jìn)程調(diào)度和時(shí)間 第9章 存儲(chǔ)管理策略 第10章 輸入/輸出子系統(tǒng) 第11章 進(jìn)程間通信 第12章 多處理機(jī)系統(tǒng) 第13章 分布式UNIX系統(tǒng)

      ##樣章試讀:內(nèi)核導(dǎo)言

      上一章給出了對(duì)UNIX系統(tǒng)環(huán)境的高層次的看法。本章重點(diǎn)放在內(nèi)核上,對(duì)內(nèi)核的體系結(jié)構(gòu)提出一個(gè)總的看法,勾畫(huà)出它的基本概念和結(jié)構(gòu),而這些對(duì)于了解本書(shū)的其余部分是必不可少的。

      2.1 UNIX操作系統(tǒng)的體系結(jié)構(gòu)

      Christian曾提出,UNIX系統(tǒng)支持文件系統(tǒng)有“空間”而進(jìn)程有“生命”的假象(見(jiàn)[Christian 83)第239頁(yè))。文件和進(jìn)程這兩類(lèi)實(shí)體是UNIX系統(tǒng)模型中的兩個(gè)中心概念。圖2-1給出了內(nèi)核框圖,顯示出了各種模塊及它們之間的相互關(guān)系,尤其是,它顯示出了內(nèi)核的兩個(gè)主要成分:左邊的文件子系統(tǒng)和右邊的進(jìn)程控制子系統(tǒng)。雖然在實(shí)際上,由于某些模塊同其他模塊的內(nèi)部操作進(jìn)行交互而使內(nèi)核偏離該模型,但該圖仍可作為觀察內(nèi)核的一個(gè)有用的邏輯視圖。

      圖2-1讓我們看到了三個(gè)層次:用戶(hù)級(jí)、內(nèi)核級(jí)及硬件級(jí)。系統(tǒng)調(diào)用與庫(kù)接口體現(xiàn)了圖1-1中描繪的用戶(hù)程序與內(nèi)核間的邊界。系統(tǒng)調(diào)用看起來(lái)像C程序中普通的函數(shù)調(diào)用,而庫(kù)把這些函數(shù)調(diào)用映射成進(jìn)入操作系統(tǒng)所需要的原語(yǔ)。這在第6章中有更詳細(xì)的敘述。然而,匯編語(yǔ)言程序可以不經(jīng)過(guò)系統(tǒng)調(diào)用庫(kù)而直接引用系統(tǒng)調(diào)用。程序常常使用像標(biāo)準(zhǔn)I/O庫(kù)這樣的一些其他庫(kù)程序以提供對(duì)系統(tǒng)調(diào)用的更高級(jí)的使用。在編譯期間把這些庫(kù)連接到程序上,因此,就這里所討論的目的來(lái)說(shuō),這些庫(kù)是用戶(hù)程序的一部分。下面的一個(gè)例子將闡明這一點(diǎn)。

      圖2-1把系統(tǒng)調(diào)用的集合分成與文件子系統(tǒng)交互的部分以及與進(jìn)程控制子系統(tǒng)交互的部分。文件子系統(tǒng)管理文件,其中包括分配文件空間、管理空閑空間、控制對(duì)文件的存取以及為用戶(hù)檢索數(shù)據(jù)。進(jìn)程通過(guò)一個(gè)特定的系統(tǒng)調(diào)用集合,比如,通過(guò)系統(tǒng)調(diào)用open(為了讀或?qū)懚蜷_(kāi)一個(gè)文件)、close、read、write、stat(查詢(xún)一個(gè)文件屬性)、chown(改變文件所有者)及chmod(改變文件存取許可權(quán))等與文件子系統(tǒng)交互。這些及另外一些有關(guān)的系統(tǒng)調(diào)用將在第5章介紹。

      文件子系統(tǒng)使用一個(gè)緩沖機(jī)制存取文件數(shù)據(jù),緩沖機(jī)制調(diào)節(jié)在內(nèi)核與二級(jí)存儲(chǔ)設(shè)備之間的數(shù)據(jù)流。緩沖機(jī)制同塊I/O設(shè)備驅(qū)動(dòng)程序交互,以便啟動(dòng)往內(nèi)核去的數(shù)據(jù)傳送及從內(nèi)核來(lái)的數(shù)據(jù)傳送。設(shè)備驅(qū)動(dòng)程序是用來(lái)控制外圍設(shè)備操作的內(nèi)核模塊。塊I/O設(shè)備是隨機(jī)存取存儲(chǔ)設(shè)備,或者說(shuō),它們的設(shè)備驅(qū)動(dòng)程序使得它們對(duì)于系統(tǒng)的其他部分來(lái)說(shuō)好像是隨機(jī)存取存儲(chǔ)設(shè)備。例如,一個(gè)磁帶驅(qū)動(dòng)程序可以允許內(nèi)核把一個(gè)磁帶裝置作為一個(gè)隨機(jī)存取存儲(chǔ)設(shè)備看待。文件子系統(tǒng)還可以在沒(méi)有緩沖機(jī)制干預(yù)的情況下直接與“原始”I/O設(shè)備驅(qū)動(dòng)程序交互。原始設(shè)備,有時(shí)被稱(chēng)為字符設(shè)備,包括所有不是塊設(shè)備的設(shè)備。

      圖2-1 系統(tǒng)內(nèi)核框圖

      進(jìn)程控制子系統(tǒng)負(fù)責(zé)進(jìn)程同步、進(jìn)程間通信、存儲(chǔ)管理及進(jìn)程調(diào)度。當(dāng)要執(zhí)行一個(gè)文件而把該文件裝入存儲(chǔ)器中時(shí),文件子系統(tǒng)與進(jìn)程控制子系統(tǒng)交互——進(jìn)程子系統(tǒng)在執(zhí)行可執(zhí)行文件之前,把它們讀到主存中。這些我們將在第7章看到。

      用于控制進(jìn)程的系統(tǒng)調(diào)用有fork(創(chuàng)建一個(gè)新進(jìn)程)、exec(把一個(gè)程序的映象覆蓋到正在運(yùn)行的進(jìn)程上)、exit(結(jié)束一個(gè)進(jìn)程的執(zhí)行)、wait(使進(jìn)程的執(zhí)行與先前創(chuàng)建的一個(gè)進(jìn)程的exit相同步)、brk(控制分配給一個(gè)進(jìn)程的存儲(chǔ)空間的大小)及signal(控制進(jìn)程對(duì)特別事件的響應(yīng))。第7章將介紹這些及其他系統(tǒng)調(diào)用。

      存儲(chǔ)管理模塊控制存儲(chǔ)分配。在任何時(shí)刻,只要系統(tǒng)沒(méi)有足夠的物理存儲(chǔ)供所有進(jìn)程使用,內(nèi)核就在主存與二級(jí)存儲(chǔ)之間對(duì)進(jìn)程進(jìn)行遷移,以便所有進(jìn)程都得到公平的執(zhí)行機(jī)會(huì)。第9章將描述存儲(chǔ)管理的兩個(gè)策略:對(duì)換與請(qǐng)求調(diào)頁(yè)。對(duì)換進(jìn)程有時(shí)被稱(chēng)為調(diào)度程序,因?yàn)樗鼮檫M(jìn)程進(jìn)行存儲(chǔ)分配的調(diào)度,并且影響到CPU調(diào)度程序的操作。然而,本書(shū)仍將稱(chēng)它為對(duì)換程序,以避免與CPU調(diào)度程序混淆。

      調(diào)度程序(scheduler)模塊把CPU分配給進(jìn)程。該模塊調(diào)度各進(jìn)程依次運(yùn)行,直到它們因等待資源自愿放棄CPU,或它們最近一次的運(yùn)行時(shí)間超過(guò)一個(gè)時(shí)間量,從而內(nèi)核搶占它們。于是調(diào)度程序選擇最高優(yōu)先權(quán)的合格進(jìn)程投入運(yùn)行;當(dāng)原來(lái)的進(jìn)程成為最高優(yōu)先權(quán)的合格進(jìn)程時(shí),還會(huì)再次投入運(yùn)行。進(jìn)程間通信有幾種形式,從事件的異步軟中斷信號(hào)到進(jìn)程間消息的同步傳輸,等等。

      最后,硬件控制負(fù)責(zé)處理中斷及與機(jī)器通信。像磁盤(pán)或終端這樣的設(shè)備可以在一個(gè)進(jìn)程正在執(zhí)行時(shí)中斷CPU。如果出現(xiàn)這種情況,在對(duì)中斷服務(wù)完畢之后內(nèi)核可以恢復(fù)被中斷了的進(jìn)程的執(zhí)行:中斷不是由特殊的進(jìn)程服務(wù)的,而是由內(nèi)核中的特殊函數(shù)服務(wù)的,這些特殊函數(shù)是在當(dāng)前運(yùn)行的進(jìn)程的上下文中被調(diào)用的。

      2.2 系統(tǒng)概念介紹

      本節(jié)將概述一些主要的內(nèi)核數(shù)據(jù)結(jié)構(gòu),并且更詳細(xì)地描述圖2-1中給出的各模塊的功能。

      2.2.1 文件子系統(tǒng)概貌

      一個(gè)文件的內(nèi)部表示由一個(gè)索引節(jié)點(diǎn)(inode)給出,索引節(jié)點(diǎn)描述了文件數(shù)據(jù)在磁盤(pán)上的布局,并且包含諸如文件所有者、存取許可權(quán)及存取時(shí)間等其他信息。“索引節(jié)點(diǎn)”這一術(shù)語(yǔ)是index node的縮寫(xiě),并且普遍地用于UNIX系統(tǒng)的文獻(xiàn)中。每個(gè)文件都有一個(gè)索引節(jié)點(diǎn),但是它可以有幾個(gè)名字,且這幾個(gè)名字都映射到該索引節(jié)點(diǎn)上。每個(gè)名字都被稱(chēng)為一個(gè)聯(lián)結(jié)(link)。當(dāng)進(jìn)程使用名字訪問(wèn)一個(gè)文件時(shí),內(nèi)核每次分析文件名中的一個(gè)分量,檢查該進(jìn)程是否有權(quán)搜索路徑中的目錄,并且最終檢索到該文件所對(duì)應(yīng)的索引節(jié)點(diǎn)。例如,如果一個(gè)進(jìn)程調(diào)用

      open(?“/fs2/mjb/rje/sourcefile”,1);

      則內(nèi)核檢查“/fs2/mjb/rje/sourcefile”所對(duì)應(yīng)的索引節(jié)點(diǎn)。當(dāng)一個(gè)進(jìn)程建立一個(gè)新文件時(shí),內(nèi)核分配給它一個(gè)尚未使用的索引節(jié)點(diǎn)。正如我們很快就會(huì)看到的那樣,索引節(jié)點(diǎn)被存儲(chǔ)在文件系統(tǒng)中,但是當(dāng)操控文件時(shí),內(nèi)核把它們讀到內(nèi)存(in-core)[1]

      索引節(jié)點(diǎn)表中。

      內(nèi)核還包含另外兩個(gè)數(shù)據(jù)結(jié)構(gòu),文件表(file table)和用戶(hù)文件描述符表(user file descriptor table)。文件表是一個(gè)全局核心結(jié)構(gòu),但用戶(hù)文件描述符表對(duì)每個(gè)進(jìn)程分配一個(gè)。當(dāng)一個(gè)進(jìn)程打開(kāi)或建立一個(gè)文件時(shí),內(nèi)核在每個(gè)表中為相應(yīng)于該文件的索引節(jié)點(diǎn)分配一個(gè)表項(xiàng)。這樣一共有三種結(jié)構(gòu)表——用戶(hù)文件描述符表、文件表和索引結(jié)點(diǎn)表(inode table),用這三種結(jié)構(gòu)表中的表項(xiàng)來(lái)維護(hù)文件的狀態(tài)及用戶(hù)對(duì)它的存取。文件表保存著文件中的字節(jié)偏移量——下一次讀或?qū)憣哪抢镩_(kāi)始,并保存著對(duì)打開(kāi)的進(jìn)程所允許的存取權(quán)限。用戶(hù)文件描述符表標(biāo)識(shí)著一個(gè)進(jìn)程的所有打開(kāi)文件。圖2-2表明了這三張表及它們之間的相互關(guān)系。對(duì)于系統(tǒng)調(diào)用open和系統(tǒng)調(diào)用creat,內(nèi)核返回一個(gè)文件描述符(file descriptor),它是在用戶(hù)文件描述符表中的索引值。當(dāng)執(zhí)行系統(tǒng)調(diào)用read和write時(shí),內(nèi)核使用文件描述符以存取用戶(hù)文件描述符表,循著指向文件表及索引節(jié)點(diǎn)表表項(xiàng)的指針,從索引節(jié)點(diǎn)中找到文件中的數(shù)據(jù)。第4章和第5章將詳細(xì)地描述這些結(jié)構(gòu),此刻,我們只要說(shuō)使用這三張表可以實(shí)現(xiàn)對(duì)一個(gè)文件的不同程度的存取共享就夠了。

      圖2-2 文件描述符表、文件表和索引節(jié)點(diǎn)表

      UNIX系統(tǒng)把正規(guī)文件(regular file)及目錄保存在諸如磁帶或磁盤(pán)這樣的塊設(shè)備上。由于磁帶和磁盤(pán)在存取時(shí)間上的差別,所以沒(méi)有什么UNIX系統(tǒng)裝置使用磁帶實(shí)現(xiàn)它們的文件系統(tǒng)。今后,無(wú)盤(pán)工作站將用得很普遍。在無(wú)盤(pán)工作站中,文件被存放在一個(gè)遠(yuǎn)程系統(tǒng)上,并通過(guò)網(wǎng)絡(luò)進(jìn)行存取(見(jiàn)第13章)。然而,為簡(jiǎn)單起見(jiàn),下面假設(shè)討論的是有磁盤(pán)的系統(tǒng)。一套系統(tǒng)裝置可以有若干物理磁盤(pán)設(shè)備,每個(gè)物理磁盤(pán)設(shè)備包含一個(gè)或多個(gè)文件系統(tǒng)。把一個(gè)磁盤(pán)分成幾個(gè)文件系統(tǒng)可以使管理人員易于管理存儲(chǔ)在那兒的數(shù)據(jù)。內(nèi)核在邏輯級(jí)上只涉及文件系統(tǒng),而不涉及磁盤(pán),把每個(gè)文件系統(tǒng)都當(dāng)作由一個(gè)邏輯設(shè)備號(hào)標(biāo)識(shí)的邏輯設(shè)備(logical device)。由磁盤(pán)驅(qū)動(dòng)程序?qū)崿F(xiàn)邏輯設(shè)備(文件系統(tǒng))地址與物理設(shè)備(磁盤(pán))地址之間的轉(zhuǎn)換。除非另有明確的說(shuō)明,否則,本書(shū)在使用“設(shè)備”這一術(shù)語(yǔ)時(shí)總是意味著一個(gè)邏輯設(shè)備。

      一個(gè)文件系統(tǒng)由一個(gè)邏輯塊(logical block)序列組成,每個(gè)塊都包含512、1024、2048 個(gè)字節(jié)或512個(gè)字節(jié)的任意倍數(shù),這要依賴(lài)于系統(tǒng)實(shí)現(xiàn)。在一個(gè)文件系統(tǒng)中,邏輯塊大小是完全相同的,但是在一個(gè)系統(tǒng)配置中的不同文件系統(tǒng)間邏輯塊大小可以是不同的。使用大的邏輯塊增加了在磁盤(pán)與主存之間的有效數(shù)據(jù)傳送率,因?yàn)閮?nèi)核在每次磁盤(pán)操作中能傳送較多的數(shù)據(jù),所以只執(zhí)行很少幾次費(fèi)時(shí)的操作。比如,一次從磁盤(pán)讀1KB的讀操作,會(huì)比讀兩次每次讀512B的操作要快。然而,正如將在第5章中看到的那樣,如果一個(gè)邏輯塊太大,將失去有效的存儲(chǔ)能力。為簡(jiǎn)單起見(jiàn),本書(shū)將使用“塊”這一術(shù)語(yǔ)表示一個(gè)邏輯塊,并且它將假設(shè)一個(gè)邏輯塊包含1KB數(shù)據(jù),除非另有明確說(shuō)明。

      一個(gè)文件系統(tǒng)具有如下結(jié)構(gòu)(圖2-3):

      圖2-3 文件系統(tǒng)布局

      引導(dǎo)塊(boot block)占據(jù)文件系統(tǒng)的開(kāi)頭,典型地,是一個(gè)扇區(qū)。它可以含有被讀入機(jī)器中起引導(dǎo)或初啟操作系統(tǒng)作用的引導(dǎo)代碼。雖然為了引導(dǎo)系統(tǒng)只需一個(gè)引導(dǎo)塊,但每個(gè)文件系統(tǒng)都有一個(gè)(可能是空的)引導(dǎo)塊。

      超級(jí)塊(super block)描述了文件系統(tǒng)的狀態(tài)——如它有多大,它能存儲(chǔ)多少文件,在文件系統(tǒng)的何處可找到空閑空間,以及其他信息。

      索引節(jié)點(diǎn)表(inode list)是一張裝有索引節(jié)點(diǎn)的表,它在文件系統(tǒng)中跟在超級(jí)塊后面。當(dāng)配置一個(gè)文件系統(tǒng)時(shí),管理人員應(yīng)指明索引節(jié)點(diǎn)表的大小。內(nèi)核通過(guò)索引來(lái)訪問(wèn)索引節(jié)點(diǎn)表中的索引節(jié)點(diǎn)。有一個(gè)索引節(jié)點(diǎn)是文件系統(tǒng)的根索引節(jié)點(diǎn)(root inode):在執(zhí)行了系統(tǒng)調(diào)用mount(見(jiàn)5.14節(jié))之后,該文件系統(tǒng)的目錄結(jié)構(gòu)就可以從這個(gè)根索引節(jié)點(diǎn)開(kāi)始進(jìn)行存取了。

      數(shù)據(jù)塊(data block)在索引節(jié)點(diǎn)表結(jié)束后開(kāi)始,并且包含文件數(shù)據(jù)與管理數(shù)據(jù)。一個(gè)已被分配的數(shù)據(jù)塊,能且僅能屬于文件系統(tǒng)中的一個(gè)文件。

      2.2.2 進(jìn)程

      本節(jié)將更進(jìn)一步介紹進(jìn)程子系統(tǒng):先描述一個(gè)進(jìn)程的結(jié)構(gòu)及用于存儲(chǔ)管理的若干進(jìn)程數(shù)據(jù)結(jié)構(gòu);然后給出進(jìn)程狀態(tài)圖的初步看法,并考慮狀態(tài)轉(zhuǎn)換中的各種問(wèn)題。

      一個(gè)進(jìn)程是一個(gè)程序的執(zhí)行,它是由一系列有格式字節(jié)組成的,這些有格式字節(jié)被解釋成機(jī)器指令[以下被稱(chēng)為“正文(text)”]、數(shù)據(jù)和棧區(qū)(stack)。當(dāng)內(nèi)核調(diào)度各個(gè)進(jìn)程使之執(zhí)行時(shí),這些進(jìn)程看起來(lái)像是同時(shí)執(zhí)行的。而且,可以有幾個(gè)進(jìn)程是一個(gè)程序的實(shí)例。一個(gè)進(jìn)程循著一個(gè)嚴(yán)格的指令序列執(zhí)行,這個(gè)指令序列是自包含的,并且不會(huì)跳轉(zhuǎn)到別的進(jìn)程的指令序列上。它讀或?qū)懽约旱臄?shù)據(jù)和棧區(qū),但它不能讀或?qū)懫渌M(jìn)程的數(shù)據(jù)和棧區(qū)。進(jìn)程通過(guò)系統(tǒng)調(diào)用與其他進(jìn)程及外界進(jìn)行通信。

      用實(shí)際的術(shù)語(yǔ)來(lái)說(shuō),UNIX系統(tǒng)上的進(jìn)程是被系統(tǒng)調(diào)用fork所創(chuàng)建的實(shí)體。除了0進(jìn)程以外,每個(gè)進(jìn)程都是被另一個(gè)進(jìn)程執(zhí)行系統(tǒng)調(diào)用fork時(shí)創(chuàng)建的。調(diào)用系統(tǒng)調(diào)用fork的進(jìn)程是父進(jìn)程(parent process),而新創(chuàng)建的進(jìn)程是子進(jìn)程(child process)。每個(gè)進(jìn)程都有一個(gè)父進(jìn)程,但一個(gè)進(jìn)程可以有多個(gè)子進(jìn)程。內(nèi)核用各進(jìn)程的進(jìn)程標(biāo)識(shí)號(hào)(process ID)來(lái)標(biāo)識(shí)每個(gè)進(jìn)程,進(jìn)程標(biāo)識(shí)號(hào)簡(jiǎn)稱(chēng)為進(jìn)程ID(或PID,見(jiàn)第6章)。0進(jìn)程是一個(gè)特殊進(jìn)程,它是在系統(tǒng)引導(dǎo)時(shí)被“手工”創(chuàng)建的;當(dāng)它創(chuàng)建了一個(gè)子進(jìn)程(1進(jìn)程)之后,0進(jìn)程就變成對(duì)換進(jìn)程。正如在第7章所解釋的那樣,1進(jìn)程被稱(chēng)為init進(jìn)程,是系統(tǒng)中其他每個(gè)進(jìn)程的祖先,并且享有同它們之間的特殊關(guān)系。

      用戶(hù)對(duì)一個(gè)程序的源代碼進(jìn)行編譯以建立一個(gè)可執(zhí)行文件,可執(zhí)行文件由以下幾部分組成:

      描述文件屬性的一組“頭標(biāo)(header)”;

      程序正文;

      數(shù)據(jù)的機(jī)器語(yǔ)言表示,它給出程序開(kāi)始執(zhí)行時(shí)的初值;一個(gè)空間指示,它指出內(nèi)核應(yīng)該為被稱(chēng)為bss[2]

      的未初始化數(shù)據(jù)分配多大的空間(在運(yùn)行時(shí)內(nèi)核把bss的初值置為0); - 其他段,諸如符號(hào)表信息。

      對(duì)于圖1-3中的程序,可執(zhí)行文件的正文是函數(shù)main與copy所生成的代碼,其中,變量version是初始化數(shù)據(jù)(放在本程序中僅僅是為讓它有初始化數(shù)據(jù)),數(shù)組buffer是未初始化的數(shù)據(jù)。系統(tǒng)Ⅴ的C編譯程序版本在缺省時(shí)創(chuàng)建一個(gè)分離的正文段,但它支持一種選擇,該選擇允許數(shù)據(jù)段中包含程序指令,這是在系統(tǒng)的較老的版本中使用的。

      在系統(tǒng)調(diào)用exec期間,內(nèi)核把一個(gè)可執(zhí)行文件裝入主存中,被裝入的進(jìn)程至少由被稱(chēng)為正文區(qū)、數(shù)據(jù)區(qū)及棧區(qū)的三部分組成。正文區(qū)和數(shù)據(jù)區(qū)相應(yīng)于可執(zhí)行文件中的正文段和數(shù)據(jù)bss段。但是棧區(qū)是自動(dòng)創(chuàng)建的,而且它的大小在運(yùn)行時(shí)是被內(nèi)核動(dòng)態(tài)調(diào)節(jié)的。棧區(qū)由邏輯棧幀(stack frame)組成,當(dāng)調(diào)用一個(gè)函數(shù)時(shí)棧幀被壓入,當(dāng)返回時(shí)棧幀被彈出。一個(gè)稱(chēng)為棧指針(stack pointer)的特殊寄存器指示出當(dāng)前棧深度。一個(gè)棧幀包含著用于函數(shù)調(diào)用的參數(shù)、它的邏輯變量及為恢復(fù)先前的棧幀所需要的數(shù)據(jù)——其中包括函數(shù)調(diào)用時(shí)程序計(jì)數(shù)器的值及棧指針的值。程序代碼包含管理?xiàng)T鲩L(zhǎng)的指令序列,并且當(dāng)需要時(shí)內(nèi)核為棧區(qū)分配空間。在圖1-3所示的程序中,當(dāng)main被調(diào)用時(shí)(按慣例,在每個(gè)程序中被調(diào)用一次),函數(shù)main中的參數(shù)argc和argv、變量fdold和fdnew就會(huì)在棧區(qū)上出現(xiàn)。并且,無(wú)論何時(shí)函數(shù)copy被調(diào)用,copy中的參數(shù)old與new及變量count都在棧區(qū)上出現(xiàn)。

      因?yàn)閁NIX系統(tǒng)中的一個(gè)進(jìn)程能在兩種態(tài)——核心態(tài)(kernel mode)或用戶(hù)態(tài)(user mode)下執(zhí)行,所以UNIX系統(tǒng)中核心棧(kernel stack)與用戶(hù)棧(user stack)是分開(kāi)的。用戶(hù)棧含有在用戶(hù)態(tài)下執(zhí)行時(shí)函數(shù)調(diào)用的參數(shù)、局部變量及其他數(shù)據(jù)。圖2-4中的左半部表明一個(gè)進(jìn)程在copy程序中做系統(tǒng)調(diào)用write時(shí)進(jìn)程的用戶(hù)棧。進(jìn)程啟動(dòng)過(guò)程(此過(guò)程是包含在庫(kù)中的)用兩個(gè)參數(shù)調(diào)用函數(shù)main,并將第1幀壓入用戶(hù)棧;第1幀含有main的兩個(gè)局部變量的空間。然后main用兩個(gè)參數(shù)old與new調(diào)用copy,并將第2幀壓入用戶(hù)棧中,第2幀包含局部變量count的空間。最后,進(jìn)程通過(guò)調(diào)用庫(kù)函數(shù)write來(lái)引用系統(tǒng)調(diào)用write,每個(gè)系統(tǒng)調(diào)用都在系統(tǒng)調(diào)用庫(kù)中有一個(gè)入口點(diǎn);系統(tǒng)調(diào)用庫(kù)按匯編語(yǔ)言編碼并包含一個(gè)特殊的trap指令,當(dāng)該指令被執(zhí)行時(shí),它引起一個(gè)“中斷”,從而導(dǎo)致硬件轉(zhuǎn)換到核心態(tài)。一個(gè)進(jìn)程調(diào)用一個(gè)特定的系統(tǒng)調(diào)用庫(kù)的入口點(diǎn),正像它調(diào)用任何函數(shù)一樣。對(duì)于庫(kù)函數(shù)也要?jiǎng)?chuàng)建一個(gè)棧幀。當(dāng)進(jìn)程執(zhí)行特定的指令時(shí),它將處理機(jī)執(zhí)行態(tài)轉(zhuǎn)換到核心態(tài),執(zhí)行內(nèi)核代碼,并使用核心棧。

      核心棧中含有在核心態(tài)下執(zhí)行的函數(shù)的棧幀。核心棧上的函數(shù)及數(shù)據(jù)項(xiàng)涉及的是內(nèi)核中的而不是用戶(hù)程序中的函數(shù)和數(shù)據(jù),但它的構(gòu)成與用戶(hù)棧的構(gòu)成相同。當(dāng)一個(gè)進(jìn)程在用戶(hù)態(tài)下執(zhí)行時(shí),它的核心棧為空。圖2-4的右半部給出了一個(gè)在copy程序中執(zhí)行系統(tǒng)調(diào)用write的進(jìn)程的核心棧的表項(xiàng)。在以后的章節(jié)中對(duì)系統(tǒng)調(diào)用write進(jìn)行詳細(xì)討論時(shí),再敘述各算法名稱(chēng)。

      圖2-4 程序copy的用戶(hù)棧及核心棧

      每個(gè)進(jìn)程在內(nèi)核進(jìn)程表(process table)中都有一個(gè)表項(xiàng),并且每個(gè)進(jìn)程都被分配一個(gè)u區(qū)[3]

      ,u區(qū)包含僅被內(nèi)核操縱的私用數(shù)據(jù)。進(jìn)程表包含(或指向)一個(gè)本進(jìn)程區(qū)表(per process region table),本進(jìn)程區(qū)表的表項(xiàng)指向區(qū)表(region table)的表項(xiàng)。一個(gè)區(qū)是進(jìn)程地址空間中連續(xù)的區(qū)域,如正文區(qū)、數(shù)據(jù)區(qū)及棧區(qū)等。區(qū)表登記項(xiàng)描述區(qū)的屬性,諸如它是否包含正文或數(shù)據(jù),它是共享的還是私用的,以及區(qū)的“數(shù)據(jù)”位于主存的何處,等等。從本進(jìn)程區(qū)表到區(qū)表的額外伺接級(jí)允許彼此獨(dú)立的進(jìn)程對(duì)區(qū)的共享。當(dāng)一個(gè)進(jìn)程調(diào)用系統(tǒng)調(diào)用exec時(shí),在釋放了進(jìn)程一直在使用著的老區(qū)之后,內(nèi)核為它的正文、數(shù)據(jù)和棧分配新區(qū)。當(dāng)一個(gè)進(jìn)程調(diào)用系統(tǒng)調(diào)用fork時(shí),內(nèi)核拷貝老進(jìn)程的地址空間,在可能時(shí)允許進(jìn)程對(duì)區(qū)共享,否則再建立一個(gè)物理拷貝。當(dāng)一個(gè)進(jìn)程調(diào)用系統(tǒng)調(diào)用exit時(shí),內(nèi)核釋放進(jìn)程使用過(guò)的區(qū)。圖2-5展示了一個(gè)運(yùn)行中的進(jìn)程的有關(guān)數(shù)據(jù)結(jié)構(gòu):進(jìn)程表指向本進(jìn)程區(qū)表,本進(jìn)程區(qū)表有指向該進(jìn)程的正文區(qū)、數(shù)據(jù)區(qū)或棧區(qū)的區(qū)表表項(xiàng)的指針。

      圖2-5 進(jìn)程的數(shù)據(jù)結(jié)構(gòu)

      進(jìn)程表表項(xiàng)及u區(qū)包含進(jìn)程的控制信息和狀態(tài)信息。u區(qū)是進(jìn)程表表項(xiàng)的擴(kuò)展,第6章將介紹這兩個(gè)表的區(qū)別。在后幾章中討論的進(jìn)程表中的字段如下。

      狀態(tài)字段。

      標(biāo)識(shí)符——表示擁有該進(jìn)程的用戶(hù)(用戶(hù)ID或UID,見(jiàn)第6章)。

      當(dāng)一個(gè)進(jìn)程被掛起(在sleep狀態(tài))時(shí)的事件描述符集合。

      u?區(qū)包含的是用來(lái)描述進(jìn)程的信息,這些信息僅當(dāng)進(jìn)程正在執(zhí)行時(shí)才是可存取的。重要的字段如下。

      指向當(dāng)前正在執(zhí)行的進(jìn)程的進(jìn)程表項(xiàng)的指針。

      當(dāng)前系統(tǒng)調(diào)用的參數(shù),返回值及錯(cuò)誤碼。

      所有的打開(kāi)文件的文件描述符。

      內(nèi)部I/O參數(shù)。

      當(dāng)前目錄(current directory)和當(dāng)前根(current root)(見(jiàn)第5章)。

      進(jìn)程及文件大小的限制。

      內(nèi)核能直接存取正在執(zhí)行的進(jìn)程的u區(qū)的字段,但不能存取其他進(jìn)程的u區(qū)的字段。在其內(nèi)部,內(nèi)核引用結(jié)構(gòu)變量u以存取當(dāng)前正在運(yùn)行的進(jìn)程的u區(qū),并且當(dāng)另一進(jìn)程執(zhí)行時(shí),內(nèi)核重新安排它的虛地址空間,以使結(jié)構(gòu)變量u引用的是新進(jìn)程的u區(qū)。由于這一實(shí)現(xiàn)方式給出了從u區(qū)到它的進(jìn)程表表項(xiàng)的指針,所以?xún)?nèi)核很容易識(shí)別出當(dāng)前進(jìn)程。

      一個(gè)進(jìn)程的上下文(context)包括被進(jìn)程正文所定義的進(jìn)程狀態(tài)、進(jìn)程的全局用戶(hù)變量和數(shù)據(jù)結(jié)構(gòu)的值、它使用的機(jī)器寄存器的值、存儲(chǔ)在它的進(jìn)程表項(xiàng)與u區(qū)中的值以及它的用戶(hù)棧和核心棧的內(nèi)容。操作系統(tǒng)的正文和它的全局?jǐn)?shù)據(jù)結(jié)構(gòu)被所有的進(jìn)程所共享,因而不是進(jìn)程上下文的一部分。

      當(dāng)執(zhí)行一個(gè)進(jìn)程時(shí),系統(tǒng)被說(shuō)成在該進(jìn)程的上下文中執(zhí)行。當(dāng)內(nèi)核決定它應(yīng)該執(zhí)行另一個(gè)進(jìn)程時(shí),它做一次上下文切換(context switch),以使系統(tǒng)在另一個(gè)進(jìn)程的上下文中執(zhí)行。正如將要看到的,內(nèi)核僅允許在指定條件下進(jìn)行上下文切換。當(dāng)進(jìn)行上下文切換時(shí),內(nèi)核保留足夠信息,為的是以后它能切換回第一個(gè)進(jìn)程,并恢復(fù)它的執(zhí)行。類(lèi)似地,當(dāng)從用戶(hù)態(tài)移到核心態(tài)時(shí),內(nèi)核保留足夠信息以便它后來(lái)能返回到用戶(hù)態(tài),并從它的斷點(diǎn)繼續(xù)執(zhí)行。在用戶(hù)態(tài)與核心態(tài)之間的移動(dòng)是態(tài)的改變,而不是上下文切換。再看一下圖1-5,當(dāng)它把上下文從進(jìn)程A變成進(jìn)程B時(shí),內(nèi)核做的是上下文切換;當(dāng)發(fā)生從用戶(hù)態(tài)到核心態(tài)或從內(nèi)核態(tài)到用戶(hù)態(tài)的改變時(shí),所改變的是執(zhí)行態(tài),但仍在同一個(gè)進(jìn)程(例如進(jìn)程A)的上下文中執(zhí)行。

      內(nèi)核在被中斷了的進(jìn)程的上下文中對(duì)中斷服務(wù),即使該中斷可能不是由它引起的。被中斷的進(jìn)程可以是正在用戶(hù)態(tài)下執(zhí)行的,也可以是正在核心態(tài)下執(zhí)行的。內(nèi)核保留足夠的信息以便它在后來(lái)能恢復(fù)被中斷了的進(jìn)程的執(zhí)行,并在核心態(tài)下對(duì)中斷進(jìn)行服務(wù)。內(nèi)核并不產(chǎn)生或調(diào)度一個(gè)特殊進(jìn)程來(lái)處理中斷。

      一個(gè)進(jìn)程的生存周期能被劃分為一組狀態(tài),每個(gè)狀態(tài)都具有一定的用來(lái)描述該進(jìn)程的特點(diǎn)。第6章將描述所有的進(jìn)程狀態(tài),但現(xiàn)在了解如下?tīng)顟B(tài)是重要的:

      (1)進(jìn)程正在用戶(hù)態(tài)下執(zhí)行。

      (2)進(jìn)程正在核心態(tài)下執(zhí)行。

      (3)進(jìn)程未正在執(zhí)行,但是它已準(zhǔn)備好運(yùn)行——一旦調(diào)度程序選中了它,它就可以投入運(yùn)行。很多進(jìn)程可以處于這一狀態(tài),而調(diào)度算法決定哪個(gè)進(jìn)程將成為下一個(gè)執(zhí)行的進(jìn)程。

      (4)進(jìn)程正在睡眠。當(dāng)進(jìn)程再也不能繼續(xù)執(zhí)行下去的時(shí)候,如正在等候I/O完成時(shí),進(jìn)程使自己進(jìn)入睡眠狀態(tài)。

      因?yàn)槿魏螘r(shí)刻一個(gè)處理機(jī)僅能執(zhí)行一個(gè)進(jìn)程,所以至多有一個(gè)進(jìn)程可以處在第一種狀態(tài)和第二種狀態(tài)。這兩個(gè)狀態(tài)相應(yīng)于兩種執(zhí)行態(tài):用戶(hù)態(tài)與核心態(tài)。

      以上描述的進(jìn)程狀態(tài)給出了進(jìn)程的一種靜態(tài)觀點(diǎn),但是,實(shí)際上,各個(gè)進(jìn)程是按照明確定義的規(guī)則連續(xù)地在各種狀態(tài)間移動(dòng)的。狀態(tài)轉(zhuǎn)換圖是一個(gè)有向圖,它的節(jié)點(diǎn)表示一個(gè)進(jìn)程能進(jìn)入的狀態(tài),而它的邊表示引起一個(gè)進(jìn)程從一種狀態(tài)到另一種狀態(tài)的事件。如果從第一種狀態(tài)到第二種狀態(tài)存在著一條邊,則這兩種狀態(tài)之間的狀態(tài)轉(zhuǎn)換是合法的。可以從一種狀態(tài)發(fā)出多個(gè)轉(zhuǎn)換,但是,就處于某種狀態(tài)的一個(gè)進(jìn)程來(lái)說(shuō),依賴(lài)于所發(fā)生的系統(tǒng)事件,完成一個(gè)且只完成一個(gè)轉(zhuǎn)換。圖2-6給出了上述定義的進(jìn)程狀態(tài)的狀態(tài)轉(zhuǎn)換圖。

      圖2-6 進(jìn)程狀態(tài)及轉(zhuǎn)換

      如前所述,在一個(gè)分時(shí)方式中,幾個(gè)進(jìn)程能同時(shí)執(zhí)行,并且它們可能都要在核心態(tài)下運(yùn)行。如果對(duì)它們?cè)诤诵膽B(tài)下的運(yùn)行不加以限制,則它們會(huì)破壞全局核心數(shù)據(jù)結(jié)構(gòu)中的信息。通過(guò)禁止任意的上下文切換和控制中斷的發(fā)生,內(nèi)核可保護(hù)它們的一致性。

      僅當(dāng)進(jìn)程從“核心態(tài)運(yùn)行”狀態(tài)轉(zhuǎn)移到“在內(nèi)存中睡眠”狀態(tài)時(shí),內(nèi)核才允許上下文切換。在核心態(tài)下運(yùn)行的進(jìn)程不能被其他進(jìn)程所搶占,因此內(nèi)核有時(shí)被稱(chēng)為不可搶先(non-preemptive)的,雖然系統(tǒng)并不搶占處于用戶(hù)態(tài)下的進(jìn)程。因?yàn)閮?nèi)核處于不可搶先狀態(tài),所以?xún)?nèi)核可保持它的數(shù)據(jù)結(jié)構(gòu)的一致性,從而解決了互斥(mutual exclusion)問(wèn)題——保證在任何時(shí)刻至多一個(gè)進(jìn)程執(zhí)行臨界區(qū)代碼。

      比如,讓我們考慮圖2-7中的示例代碼。該代碼段要把其地址在指針變量bp1中的數(shù)據(jù)結(jié)構(gòu),插入雙向鏈表中地址在指針變量bp中的數(shù)據(jù)結(jié)構(gòu)之后。如果當(dāng)內(nèi)核執(zhí)行這一代碼段時(shí)系統(tǒng)允許上下文切換,則會(huì)發(fā)生如下情形。假設(shè)直到注釋出現(xiàn)之前內(nèi)核執(zhí)行該代碼,然后做一個(gè)上下文切換,這時(shí)雙向鏈表處于非一致性狀態(tài):結(jié)構(gòu)bp1一半***在該鏈表上,另一半在該鏈表外。如果進(jìn)程沿著向前的指針,則它能在該鏈表上找到bp1;但如果沿著向后的指針,則它不能找到bp1(圖2-8)。如果其他進(jìn)程在原來(lái)的進(jìn)程再次運(yùn)行之前操控鏈表上的這些指針,則雙向鏈表結(jié)構(gòu)會(huì)被永久性地毀壞。UNIX系統(tǒng)通過(guò)一個(gè)進(jìn)程在核心態(tài)下執(zhí)行時(shí)不允許上下文切換來(lái)防止這種情況發(fā)生。如果一個(gè)進(jìn)程進(jìn)入睡眠從而允許上下文切換,則必須使內(nèi)核算法的編碼實(shí)現(xiàn)能夠確保系統(tǒng)數(shù)據(jù)結(jié)構(gòu)處于安全、一致的狀態(tài)。

      圖2-7 創(chuàng)建雙鏈表的示例代碼

      圖2-8 由于上下文切換而造成的不正確鏈表

      能引起內(nèi)核數(shù)據(jù)的非一致性的有關(guān)問(wèn)題是中斷的處理。中斷處理能改變內(nèi)核狀態(tài)信息。舉例來(lái)說(shuō),如果內(nèi)核正在執(zhí)行圖2-7中的代碼,當(dāng)執(zhí)行到注釋行時(shí)接收了一個(gè)中斷,并且中斷處理程序是如前所述的那樣操縱指針,則中斷處理程序就會(huì)破壞該鏈表中的信息。若規(guī)定在核心態(tài)下執(zhí)行時(shí)系統(tǒng)禁止所有的中斷,就可以解決這一問(wèn)題。但是這可能會(huì)使中斷的服務(wù)推遲,或者可能會(huì)損害系統(tǒng)吞吐量,為此,改為當(dāng)進(jìn)入代碼臨界區(qū)(critical region)時(shí)內(nèi)核把處理機(jī)執(zhí)行級(jí)提高,以禁止中斷。如果任意的中斷處理程序的執(zhí)行會(huì)導(dǎo)致一致性問(wèn)題的話,那么代碼段是臨界的。比如,如果一個(gè)磁盤(pán)中斷處理程序操縱圖中的緩沖區(qū)隊(duì)列,則內(nèi)核操縱緩沖區(qū)隊(duì)列的那個(gè)代碼段是關(guān)于磁盤(pán)中斷處理程序的代碼臨界區(qū)。臨界區(qū)應(yīng)小且不經(jīng)常出現(xiàn),以便系統(tǒng)吞吐量不大會(huì)被它們的存在所影響。其他操作系統(tǒng)解決這一問(wèn)題的方法是:規(guī)定在系統(tǒng)狀態(tài)下執(zhí)行時(shí)封鎖所有的中斷,或者采用完善的加鎖方案以保證一致性。第12章將面對(duì)多處理機(jī)系統(tǒng)再回過(guò)頭來(lái)討論這一問(wèn)題。這里所給出的解答在那時(shí)就不夠了。

      現(xiàn)在讓我們回顧一下本節(jié)的內(nèi)容:內(nèi)核通過(guò)僅當(dāng)一個(gè)進(jìn)程使自己進(jìn)入睡眠時(shí)才允許上下文切換,以及通過(guò)禁止一個(gè)進(jìn)程改變另一個(gè)進(jìn)程的狀態(tài)來(lái)保護(hù)它的一致性。它還在代碼臨界區(qū)周?chē)岣咛幚頇C(jī)執(zhí)行級(jí),以封鎖其他能引起非一致性的中斷。進(jìn)程調(diào)度程序定期地?fù)屨加脩?hù)態(tài)下的進(jìn)程執(zhí)行,以使進(jìn)程不能獨(dú)占式地使用CPU。

      一個(gè)在核心態(tài)下執(zhí)行的進(jìn)程在決定它對(duì)系統(tǒng)事件的反應(yīng)上它打算做什么方面有很大的自主權(quán)。進(jìn)程能互相通信并且“建議”各種可供選擇的方法,但由它們自己做出最后的決定。正如我們將要看到的,存在著一組進(jìn)程在面臨各種情況時(shí)所應(yīng)服從的規(guī)則,但是每個(gè)進(jìn)程最終都是自主地遵循這些規(guī)則的。例如,當(dāng)一個(gè)進(jìn)程必須暫停它的執(zhí)行(“進(jìn)入睡眠”)時(shí),它能自由地按自己的意圖去做。然而,一個(gè)中斷處理程序不能睡眠,因?yàn)槿绻袛嗵幚沓绦蚰芩撸鸵馕吨恢袛嗟倪M(jìn)程會(huì)被投入睡眠。

      進(jìn)程會(huì)因?yàn)樗鼈冋诘却承┦录陌l(fā)生而進(jìn)入睡眠,例如:等待來(lái)自外圍設(shè)備的I/O完成;等待一個(gè)進(jìn)程退出;等待獲得系統(tǒng)資源;等等。當(dāng)我們說(shuō)進(jìn)程在一個(gè)事件上睡眠時(shí),這意味著,直到該事件發(fā)生時(shí),它們一直處于睡眠狀態(tài);當(dāng)事件發(fā)生時(shí)它們被喚醒,并且進(jìn)入“就緒”狀態(tài)。很多進(jìn)程能同時(shí)睡眠在一個(gè)事件上;當(dāng)一個(gè)事件發(fā)生時(shí),由于這個(gè)事件的條件再也不為真了,所以所有睡眠在這個(gè)事件上的進(jìn)程都被喚醒。當(dāng)一個(gè)進(jìn)程被喚醒時(shí),它完成一個(gè)從“睡眠”狀態(tài)到“就緒”狀態(tài)的狀態(tài)轉(zhuǎn)換,對(duì)于隨后的調(diào)度來(lái)說(shuō),該進(jìn)程就是個(gè)合格者了,但它并不立即執(zhí)行。睡眠進(jìn)程不耗費(fèi)CPU資源;內(nèi)核并不是經(jīng)常去查看一個(gè)進(jìn)程是否仍處于睡眠狀態(tài),而是等待事件的發(fā)生,那時(shí)把進(jìn)程喚醒。

      舉例來(lái)說(shuō),一個(gè)在核心態(tài)執(zhí)行的進(jìn)程有時(shí)必須鎖住一個(gè)數(shù)據(jù)結(jié)構(gòu),如果發(fā)生后來(lái)它進(jìn)入睡眠的情況,其他企圖操縱該上了鎖的數(shù)據(jù)結(jié)構(gòu)的進(jìn)程必須檢查上鎖情況,并且因?yàn)閯e的進(jìn)程已經(jīng)占有該鎖,則它們?nèi)ニ摺?nèi)核按如下方式實(shí)現(xiàn)這樣的鎖:

      它按如下方式解鎖并喚醒睡眠在該鎖上的所有進(jìn)程:

      圖2-9描繪了三個(gè)進(jìn)程A、B、C為一個(gè)上了鎖的緩沖區(qū)進(jìn)行競(jìng)爭(zhēng)的情況。睡眠的條件是緩沖區(qū)處于上鎖狀態(tài)。在任一時(shí)刻只能有一個(gè)進(jìn)程在執(zhí)行,它發(fā)現(xiàn)緩沖區(qū)是上了鎖的,就在緩沖區(qū)變?yōu)殚_(kāi)鎖狀態(tài)的事件上等待。終于,緩沖區(qū)的鎖解開(kāi)了,所有的進(jìn)程被喚醒并且進(jìn)入“就緒”狀態(tài)。內(nèi)核最終選擇一個(gè)進(jìn)程(比如說(shuō)B)執(zhí)行。進(jìn)程B執(zhí)行“while”循環(huán),發(fā)現(xiàn)緩沖區(qū)處于開(kāi)鎖狀態(tài),于是為緩沖區(qū)上鎖,并且繼續(xù)執(zhí)行。如果后來(lái)進(jìn)程B在為緩沖區(qū)解鎖之前再次去睡眠(例如等候I/O操作的完成),則內(nèi)核能調(diào)度其他進(jìn)程去運(yùn)行。如果它選擇了進(jìn)程A,進(jìn)程A執(zhí)行“while”循環(huán),發(fā)現(xiàn)緩沖區(qū)處于上鎖狀態(tài),那么它就再次去睡眠。進(jìn)程C可以做同樣的事情。最后,進(jìn)程B醒來(lái)并為緩沖區(qū)解鎖,允許進(jìn)程A也允許進(jìn)程C存取緩沖區(qū)。因此,“while-sleep”循環(huán)保證至多一個(gè)進(jìn)程能獲得對(duì)資源的存取。

      第6章將極其詳細(xì)地介紹睡眠與喚醒的算法。在此期間它們應(yīng)被考慮成是“原子的”:一個(gè)進(jìn)程瞬時(shí)地進(jìn)入睡眠狀態(tài),并停留在那兒直至它被喚醒。在它睡眠之后,內(nèi)核調(diào)度另一個(gè)進(jìn)程去運(yùn)行,并切換成后者的上下文。

      圖2-9 在一個(gè)鎖上睡眠的多個(gè)進(jìn)程

      2.3 內(nèi)核數(shù)據(jù)結(jié)構(gòu)

      大多數(shù)內(nèi)核數(shù)據(jù)結(jié)構(gòu)都占據(jù)固定長(zhǎng)度的表而不是動(dòng)態(tài)地分配空間,這一方法的優(yōu)點(diǎn)是內(nèi)核代碼簡(jiǎn)單。但是它限制了一種數(shù)據(jù)結(jié)構(gòu)的表項(xiàng)的數(shù)目,即為系統(tǒng)生成時(shí)原始配置的數(shù)目。如果在系統(tǒng)操作期間,內(nèi)核用完了一種數(shù)據(jù)結(jié)構(gòu)的表項(xiàng),則它不能動(dòng)態(tài)地為新的表項(xiàng)分配空間,而是必須向發(fā)出請(qǐng)求的用戶(hù)報(bào)告一個(gè)錯(cuò)誤。此外,如果內(nèi)核被配置得具有不可能用完的表空間,則因不能用于其他目的而使多余的表空間浪費(fèi)了。然而,一般都認(rèn)為內(nèi)核算法的簡(jiǎn)單性比擠出主存中每一個(gè)僅有的字節(jié)的必要性更重要一些。算法通常使用簡(jiǎn)單的循環(huán)來(lái)尋找表中的空閑表項(xiàng),這是一個(gè)較易于理解的方法,而且有時(shí)比復(fù)雜的分配方案更為有效。

      2.4 系統(tǒng)管理

      管理進(jìn)程可以非嚴(yán)格地歸入為用戶(hù)團(tuán)體的公共福利提供各種功能的那類(lèi)進(jìn)程。這些功能包括磁盤(pán)格式化、新文件系統(tǒng)的創(chuàng)建、修復(fù)被破壞的文件系統(tǒng)、內(nèi)核調(diào)試及其他。從概念上說(shuō),管理進(jìn)程與用戶(hù)進(jìn)程沒(méi)有區(qū)別:它們都使用為一般用戶(hù)團(tuán)體可用的相同的一組系統(tǒng)調(diào)用。它們僅在被允許的權(quán)限與特權(quán)上區(qū)別于一般用戶(hù)進(jìn)程。例如,文件存取權(quán)限允許管理進(jìn)程操縱對(duì)一般用戶(hù)來(lái)說(shuō)禁止進(jìn)入的文件。在內(nèi)部,內(nèi)核把一個(gè)稱(chēng)為超級(jí)用戶(hù)(superuser)的特殊用戶(hù)區(qū)別出來(lái),賦予它特權(quán),這一點(diǎn)我們即將看到。通過(guò)履行一次注冊(cè)-口令序列或通過(guò)執(zhí)行特殊程序可使一個(gè)用戶(hù)成為超級(jí)用戶(hù)。超級(jí)用戶(hù)特權(quán)的其他用途將在隨后的章節(jié)中研究。簡(jiǎn)而言之,內(nèi)核不識(shí)別一個(gè)分離的管理進(jìn)程類(lèi)。

      2.5 本章小結(jié)

      本章描述了內(nèi)核的體系結(jié)構(gòu):它的兩個(gè)主要成分是文件子系統(tǒng)與進(jìn)程子系統(tǒng)。文件子系統(tǒng)控制用戶(hù)文件中數(shù)據(jù)的存儲(chǔ)與檢索。文件被組織到文件系統(tǒng)中,而文件系統(tǒng)被看作一個(gè)邏輯設(shè)備。像磁盤(pán)這樣的一個(gè)物理設(shè)備能包含幾個(gè)邏輯設(shè)備(文件系統(tǒng))。每個(gè)文件系統(tǒng)都有一個(gè)用來(lái)描述文件系統(tǒng)的結(jié)構(gòu)和內(nèi)容的超級(jí)塊,并且文件系統(tǒng)中的每個(gè)文件都由索引節(jié)點(diǎn)描述,索引節(jié)點(diǎn)給出了文件的屬性。操控文件的系統(tǒng)調(diào)用通過(guò)索引節(jié)點(diǎn)來(lái)實(shí)現(xiàn)其功能。

      進(jìn)程有各種狀態(tài),并且按照明確定義的轉(zhuǎn)換規(guī)則在這些狀態(tài)之間轉(zhuǎn)移。特別之處在于,在核心態(tài)下執(zhí)行的進(jìn)程能暫停它們的執(zhí)行而進(jìn)入睡眠狀態(tài),但是沒(méi)有哪一個(gè)進(jìn)程能把另一進(jìn)程投入睡眠狀態(tài)。內(nèi)核是不可被搶占的,這意味著,一個(gè)在核心態(tài)下執(zhí)行的進(jìn)程將連續(xù)執(zhí)行,直至它進(jìn)入睡眠狀態(tài)或直至它返回到用戶(hù)態(tài)下執(zhí)行時(shí)為止。內(nèi)核通過(guò)實(shí)施不可搶占策略以及通過(guò)在執(zhí)行代碼臨界區(qū)時(shí)封鎖中斷來(lái)維護(hù)它的數(shù)據(jù)結(jié)構(gòu)的一致性。

      本章的其余部分詳細(xì)描述了圖2-1所示的子系統(tǒng)及它們的交互作用。從文件子系統(tǒng)開(kāi)始,繼之以進(jìn)程子系統(tǒng)。下一章將涉及高速緩沖問(wèn)題,并描述在第4章、第5章和第7章要介紹的算法中所使用的緩沖區(qū)分配算法。第4章考查文件系統(tǒng)的內(nèi)部算法,包括索引節(jié)點(diǎn)的操控、文件的結(jié)構(gòu)及路徑名到索引節(jié)點(diǎn)的轉(zhuǎn)換。第5章解釋若干系統(tǒng)調(diào)用,例如,系統(tǒng)調(diào)用open、close、read及write,這些系統(tǒng)調(diào)用使用了第4章中的算法來(lái)訪問(wèn)文件系統(tǒng)。第6章論述進(jìn)程上下文的基本思想及其地址空間;第7章涉及有關(guān)進(jìn)程管理及使用第6章的算法的系統(tǒng)調(diào)用;第8章介紹進(jìn)程調(diào)度;第9章討論存儲(chǔ)管理算法;第10章講的是設(shè)備驅(qū)動(dòng)程序,直到這時(shí)終端驅(qū)動(dòng)程序與進(jìn)程管理之間的相互關(guān)系才能被解釋?zhuān)坏?1章介紹了進(jìn)程間通信的某些形式;最后兩章涉及若干高級(jí)專(zhuān)題,包括多處理機(jī)系統(tǒng)與分布式系統(tǒng)。

      2.6 習(xí)題

      1.考慮如下命令序列:

      每一命令行尾部的“&”都通知shell在后臺(tái)運(yùn)行這些命令,并且它能并行地執(zhí)行每個(gè)命令。為什么這不等價(jià)于如下的命令行?

      2.考慮圖2-7中的內(nèi)核代碼示例。假設(shè)當(dāng)代碼到達(dá)注釋處時(shí)發(fā)生上下文切換,并且假設(shè)另一進(jìn)程通過(guò)執(zhí)行如下代碼而從鏈表中摘掉一個(gè)緩沖區(qū):

      考慮三種情況:

      進(jìn)程從鏈表中摘掉bp結(jié)構(gòu);

      進(jìn)程從鏈表中摘掉bp1結(jié)構(gòu);

      進(jìn)程摘掉鏈表上當(dāng)前跟在bp1之后的結(jié)構(gòu)。

      這三種情況中哪種是原來(lái)的進(jìn)程執(zhí)行完注釋以后的代碼時(shí)鏈表的狀態(tài)?

      3.如果內(nèi)核試圖喚醒睡眠在一個(gè)事件上的所有進(jìn)程,但是在喚醒時(shí)沒(méi)有進(jìn)程睡眠在那個(gè)事件上,那么會(huì)發(fā)生什么情況?

      程序員必讀經(jīng)典《UNIX操作系統(tǒng)設(shè)計(jì)》與您相約在6月

      [1] “core”這一術(shù)語(yǔ)指的是機(jī)器的原始存儲(chǔ),不是指硬件技術(shù)。

      [2] bss這一名字來(lái)自IBM 7090機(jī)的匯編偽運(yùn)算符,它代表“block started by symbol”。

      [3] u區(qū)中的u代表用戶(hù)。u區(qū)的另一個(gè)名稱(chēng)是ublock;本書(shū)則總是稱(chēng)它為u區(qū)。

      UNIX操作系統(tǒng)設(shè)計(jì)(各大網(wǎng)店已上架)

      莫里斯·J.,巴赫(Maurice J.Bach) 著,陳葆鈺,王旭,柳純錄,馮雪山 譯

      Linux之父Linux Torvalds曾捧讀的經(jīng)典著作

      UNIX操作系統(tǒng)經(jīng)典著作,暢銷(xiāo)多年

      深度剖析UNIX操作系統(tǒng)內(nèi)核的內(nèi)部數(shù)據(jù)結(jié)構(gòu)、算法和UNIX系統(tǒng)的問(wèn)題

      本書(shū)以UNIX系統(tǒng)為背景,全面、系統(tǒng)地介紹了UNIX操作系統(tǒng)內(nèi)核的內(nèi)部數(shù)據(jù)結(jié)構(gòu)和算法。本書(shū)首先對(duì)系統(tǒng)內(nèi)核結(jié)構(gòu)做了簡(jiǎn)要介紹,然后分章節(jié)描述了文件系統(tǒng)、進(jìn)程調(diào)度和存儲(chǔ)管理,并在此基礎(chǔ)上討論了UNIX系統(tǒng)的問(wèn)題,如驅(qū)動(dòng)程序接口、進(jìn)程間通信與網(wǎng)絡(luò)等。在每章之后,還給出了大量富有啟發(fā)性和實(shí)際意義的題目。

      本文轉(zhuǎn)載自異步社區(qū)。

      原文鏈接:https://www.epubit.com/articleDetails?id=Ne1d1f26f-b311-42a2-9ec0-b15bb77aaea3

      任務(wù)調(diào)度 Unix 開(kāi)發(fā)者

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶(hù)投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶(hù)投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。

      上一篇:2010excel表格的工具欄不見(jiàn)了怎么辦(excel中工具欄不見(jiàn)了怎么辦)
      下一篇:想把兩邊的空白的部分也要排字,怎么弄?(word文字兩邊留空白怎么弄)
      相關(guān)文章
      亚洲妓女综合网99| 亚洲中文字幕无码爆乳AV| 亚洲va久久久噜噜噜久久狠狠| 另类专区另类专区亚洲| 亚洲AV永久无码天堂影院| 中文日韩亚洲欧美制服| 久久精品国产99国产精品亚洲| 亚洲av无码不卡久久| 亚洲人和日本人jizz| 亚洲一区二区三区免费在线观看| 亚洲国产日韩在线| 亚洲五月激情综合图片区| 亚洲狠狠综合久久| 精品日韩亚洲AV无码| 亚洲欧洲国产成人精品| 亚洲国产福利精品一区二区 | 亚洲人成激情在线播放| 亚洲国产精品免费在线观看| 亚洲av无码一区二区三区观看| 2020久久精品亚洲热综合一本 | 国产亚洲精品成人AA片新蒲金| 国产亚洲精品精品国产亚洲综合| 国产国拍精品亚洲AV片| 久久久久久a亚洲欧洲aⅴ| 亚洲AV区无码字幕中文色| 91情国产l精品国产亚洲区| 久久亚洲sm情趣捆绑调教| 亚洲国产视频一区| 亚洲三级在线观看| 亚洲AV无码一区二区三区久久精品 | 亚洲一卡2卡3卡4卡5卡6卡| 亚洲国产综合AV在线观看| 337p日本欧洲亚洲大胆人人| 亚洲高清偷拍一区二区三区| 亚洲一区二区精品视频| 亚洲精品成人片在线播放| 亚洲图片在线观看| 亚洲av无码电影网| 狠狠入ady亚洲精品| 怡红院亚洲怡红院首页| 西西人体44rt高清亚洲 |