os2012unit2 進(jìn)程與線程_第1頁
os2012unit2 進(jìn)程與線程_第2頁
os2012unit2 進(jìn)程與線程_第3頁
os2012unit2 進(jìn)程與線程_第4頁
os2012unit2 進(jìn)程與線程_第5頁
已閱讀5頁,還剩62頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

1、Unit 2進(jìn)程與線程操作系統(tǒng)原理1CPU管理是OS的核心資源管理功能之一,其任務(wù)就是實(shí)現(xiàn)CPU的分配CPU調(diào)度。很多教科書把CPU管理歸結(jié)為進(jìn)程管理,理由是與進(jìn)程及線程密切相關(guān)。本章的內(nèi)容包括:進(jìn)程概述、進(jìn)程服務(wù)、線程。2主題進(jìn)程概念 進(jìn)程服務(wù) 線程概念31 進(jìn)程概念進(jìn)程定義進(jìn)程的基本狀態(tài)及其轉(zhuǎn)換進(jìn)程的內(nèi)存映像進(jìn)程家族41.1 進(jìn)程定義進(jìn)程是操作系統(tǒng)中最重要的基本概念。現(xiàn)代操作系統(tǒng)都以進(jìn)程作為基本的設(shè)計(jì)工具和系統(tǒng)中的基本運(yùn)行單位及資源受配單位,整個系統(tǒng)的設(shè)計(jì)是以進(jìn)程為基礎(chǔ)的。進(jìn)程(Process)的定義很多,至今也沒有一個公認(rèn)的統(tǒng)一的定義,關(guān)鍵是要理解進(jìn)程的實(shí)質(zhì)。進(jìn)程是程序在處理器上的并發(fā)執(zhí)

2、行。(Dijkstra)進(jìn)程是一個具有一定獨(dú)立功能的程序在某個數(shù)據(jù)集合上的一次運(yùn)行活動。(1987年全國操作系統(tǒng)會議)進(jìn)程是進(jìn)程映象的執(zhí)行。(UNIX)進(jìn)程是程序關(guān)于某個資源集合的一次執(zhí)行過程。(Windows)5進(jìn)程是程序處于一個執(zhí)行環(huán)境中在一個數(shù)據(jù)集上的運(yùn)行過程,它是系統(tǒng)進(jìn)行資源分配和調(diào)度的一個可并發(fā)執(zhí)行的獨(dú)立單位。(教材)簡單地說:進(jìn)程是進(jìn)展中的程序。 進(jìn)程是運(yùn)行中的程序。6 【深入理解】 進(jìn)程與程序有本質(zhì)的差異進(jìn)程和程序有著密切的聯(lián)系,但它們是兩種完全不同的概念。程序是種靜態(tài)概念。程序是一組可執(zhí)行的指令序列,平時以文件形式存放在外存中,可被長期保存,其存在可以是永久的。進(jìn)程是動態(tài)概念。

3、進(jìn)程是某個程序被裝入內(nèi)存后的一次運(yùn)行過程,具有從動態(tài)產(chǎn)生到動態(tài)消亡的生命周期,當(dāng)程序的任務(wù)執(zhí)行完時,該進(jìn)程也就隨之消亡,即進(jìn)程只是計(jì)算機(jī)系統(tǒng)中的一種暫時性的個體。進(jìn)程是程序運(yùn)行的一次動態(tài)過程,程序是進(jìn)程的靜態(tài)文本。7 列車(交通工具)程序列車的一次運(yùn)行過程進(jìn)程電影拷貝程序影片的一次放映進(jìn)程列車和電影拷貝都是可以長期存在的實(shí)體靜態(tài)物體;一次列車的運(yùn)行過程和一次影片的放映活動則有開始和結(jié)束,只延續(xù)有限的時間動態(tài)過程。8 進(jìn)程的存在依賴于特定的運(yùn)行配置每個進(jìn)程都需要執(zhí)行一定的程序,程序定義了進(jìn)程要完成的功能及算法。另外,每個進(jìn)程需要對一定的對象進(jìn)行操作,如某些數(shù)據(jù)或文件;每個進(jìn)程還需要獲取并占有一定

4、的CPU時間和一定的內(nèi)存空間等系統(tǒng)資源;此外,為了隨機(jī)地記錄進(jìn)程的運(yùn)行狀態(tài)、掌控進(jìn)程的運(yùn)行過程,操作系統(tǒng)為每個進(jìn)程動態(tài)設(shè)置有專門的數(shù)據(jù)結(jié)構(gòu)進(jìn)程控制塊(PCB)。所有這些配置了一個進(jìn)程特有的映象。進(jìn)程是在特定運(yùn)行配置下的程序運(yùn)行過程。一個進(jìn)程的形成不僅依賴于特定的程序,也依賴于特定的運(yùn)行配置(環(huán)境)。9列車運(yùn)行,除了要有列車外,還需要動力、鐵軌、車站、調(diào)度員、司乘人員及乘客貨物等構(gòu)成的列車運(yùn)行配置。電影放映,除了影片拷貝外,還需要包括影院、放映設(shè)備、影院工作人員及觀眾等。10進(jìn)程和程序不是一一對應(yīng)的一個程序與不同的運(yùn)行配置構(gòu)成的是不同的進(jìn)程,每個進(jìn)程的運(yùn)行配置都是唯一的;反之,不同的進(jìn)程可含有相

5、同的程序,即一個程序可以被多個不同的獨(dú)立進(jìn)程共享。同一列火車,在不同的時間或不同的線路上運(yùn)行,構(gòu)成的是不同車次的運(yùn)行列車。例如,同一列CRH2型列車(程序),8時從南京發(fā)往上海是D301次列車(進(jìn)程A);12時從上海發(fā)往南京則是D302次列車(進(jìn)程B)。這里進(jìn)程A和進(jìn)程B共享了同一個程序。11進(jìn)程是并發(fā)運(yùn)行的不同進(jìn)程的操作在時間上可以重疊,一個進(jìn)程的第一個操作可以在另一個進(jìn)程的最后一個操作結(jié)束之前開始。每個進(jìn)程都以各自獨(dú)立的速度向前推進(jìn),宏觀上它們是并行執(zhí)行的。但由于競爭系統(tǒng)資源,進(jìn)程之間相互制約,獲得所需資源的進(jìn)程可繼續(xù)前進(jìn),而未獲得所需資源的進(jìn)程只能暫停等待。最典型的是所有進(jìn)程都在競爭CP

6、U,某個時刻,獲得CPU的進(jìn)程可繼續(xù)執(zhí)行它的程序代碼,而其他就緒進(jìn)程都必須等待。故在微觀上,各進(jìn)程都呈現(xiàn)一種走走停停的運(yùn)行狀態(tài)。12同一線路且同一時間段上的不同列車并發(fā)運(yùn)行,相互制約。例如,在8時9時的時段上,滬寧線上有10輛列車在運(yùn)行(10個進(jìn)程并發(fā)運(yùn)行)。每一輛列車時而正在某路段上行駛(進(jìn)程執(zhí)行),時而可能正停在某個站上上下乘客或?yàn)樽屲嚩#ㄟM(jìn)程的輸入輸出進(jìn)程阻塞),也可能在某路段上被臨時停車(進(jìn)程阻塞)。在某一時刻,每一輛列車不管是正在行駛,還是到站停車,或是中途趴窩,宏觀上它們都在并發(fā)運(yùn)行中。131.2 進(jìn)程的基本狀態(tài)及其轉(zhuǎn)換進(jìn)程是一個動態(tài)實(shí)體,有自己的生命周期。一個進(jìn)程在其生命周期中

7、有多種狀態(tài),每一種狀態(tài)刻畫了進(jìn)程在不同時段的運(yùn)行行為。進(jìn)程在某個時刻總是處于某種狀態(tài)之一,隨著其自身的推進(jìn)和外界條件的變化,進(jìn)程的狀態(tài)也隨之而變。進(jìn)程的三種基本狀態(tài):執(zhí)行態(tài):進(jìn)程占有了CPU,CPU正在執(zhí)行該進(jìn)程的程序代碼。就緒態(tài):進(jìn)程已具備了執(zhí)行條件,只等系統(tǒng)將CPU分配給它(萬事具備,只欠東風(fēng))。阻塞態(tài):進(jìn)程因等待某一事件而暫時不能執(zhí)行。14進(jìn)程基本狀態(tài)的轉(zhuǎn)換 就緒執(zhí)行處于就緒態(tài)的進(jìn)程被OS的進(jìn)程調(diào)度程序選中,獲得了分配給它的的一個CPU時間周期(時間片),于是從就緒態(tài)變?yōu)閳?zhí)行態(tài)。執(zhí)行就緒導(dǎo)致這種轉(zhuǎn)換的發(fā)生有兩種情況:執(zhí)行態(tài)進(jìn)程的當(dāng)前時間片到限,發(fā)生了時間片中斷。有更高優(yōu)先級的進(jìn)程進(jìn)入了就

8、緒態(tài)。于是執(zhí)行態(tài)進(jìn)程被剝奪執(zhí)行權(quán)而變?yōu)榫途w態(tài)。執(zhí)行阻塞執(zhí)行態(tài)進(jìn)程需要等待某個事件的完成后才能繼續(xù)執(zhí)行,如讀盤文件、鍵盤輸入,因此讓出CPU而進(jìn)入阻塞態(tài)。15阻塞就緒因進(jìn)程所等待的事件完成了而被解阻喚醒,從阻塞態(tài)切換為就緒態(tài)。【強(qiáng)調(diào)】只有就緒態(tài)進(jìn)程能轉(zhuǎn)換為執(zhí)行態(tài)。阻塞態(tài)進(jìn)程被喚醒后進(jìn)入就緒態(tài),而不能直接進(jìn)入執(zhí)行態(tài)。上述各種轉(zhuǎn)換只有“執(zhí)行阻塞”是由進(jìn)程自己激發(fā)的,其他轉(zhuǎn)換都由操作系統(tǒng)激發(fā)。除了三種基本的進(jìn)程狀態(tài)外,有些系統(tǒng)還設(shè)置有掛起、死鎖、終止等狀態(tài)。16執(zhí)行就緒阻塞創(chuàng)建調(diào)度等待某事件事件發(fā)生因時間片到限等被剝奪執(zhí)行結(jié)束圖2-1 進(jìn)程基本狀態(tài)的轉(zhuǎn)換171.3 進(jìn)程的內(nèi)存映象進(jìn)程的內(nèi)存映象是進(jìn)程映

9、象的關(guān)鍵部分,也稱進(jìn)程的存儲配置或存儲實(shí)體。一個進(jìn)程的內(nèi)存映象大致包括四個部分。1. 正文段進(jìn)程的正文(主體)就是進(jìn)程需執(zhí)行的程序。用高級語言編寫的源程序一般都是可重入的“純代碼”執(zhí)行代碼空間與數(shù)據(jù)(變量)空間分離。純代碼程序可被多個進(jìn)程共享。故由高級語言生成的程序代碼也稱共享正文段。用戶進(jìn)程的正文段通常都是共享正文段。正文段中還可包括只讀的常量。182. 數(shù)據(jù)段(區(qū))用于存放程序執(zhí)行時用到的各種變量。有些系統(tǒng)把它進(jìn)一步劃分為靜態(tài)數(shù)據(jù)區(qū)和動態(tài)數(shù)據(jù)區(qū),靜態(tài)數(shù)據(jù)區(qū)用于存放靜態(tài)變量和外部變量,動態(tài)數(shù)據(jù)區(qū)則存放局部(自動)變量。3. 棧段工作區(qū)存放過程調(diào)用和系統(tǒng)調(diào)用時的調(diào)用參數(shù)和返回參數(shù)。有些系統(tǒng)還用

10、它來存放現(xiàn)場信息。棧段又可進(jìn)一步分為核心棧和用戶棧,進(jìn)程在核心態(tài)下執(zhí)行時使用的是核心棧,在用戶態(tài)下執(zhí)行時則使用用戶棧。棧段一般是進(jìn)程的私有實(shí)體。19 4. 進(jìn)程控制塊(PCB)也稱進(jìn)程表,是OS在內(nèi)存為進(jìn)程設(shè)置的專門數(shù)據(jù)結(jié)構(gòu)。每個進(jìn)程都捆綁有一個PCB,它記錄了進(jìn)程所有的靜態(tài)和動態(tài)屬性,是OS實(shí)施進(jìn)程管理與通信的最重要依據(jù)。PCB與進(jìn)程一一對應(yīng),且動態(tài)產(chǎn)生和消亡。當(dāng)為一項(xiàng)任務(wù)創(chuàng)建一個進(jìn)程時,系統(tǒng)為該進(jìn)程建立一個PCB并初始化,此后便利用PCB對進(jìn)程實(shí)施管理和控制。撤消一個進(jìn)程時,系統(tǒng)消除它的PCB,該進(jìn)程也就隨之消亡。換言之,操作系統(tǒng)是根據(jù)PCB而感知進(jìn)程的存在。從這個意義上講,PCB是進(jìn)程存

11、在的唯一標(biāo)志。PCB與進(jìn)程存儲映象中的其他實(shí)體是分離的,所有進(jìn)程的PCB被集中存放在內(nèi)核存儲區(qū),受系統(tǒng)的保護(hù)。20PCB的內(nèi)容與組織PCB一般包括以下信息:進(jìn)程基本信息:如進(jìn)程標(biāo)識數(shù)(標(biāo)識碼)PID、用戶標(biāo)識數(shù)UID、進(jìn)程的創(chuàng)建時間等。進(jìn)程家族信息:如祖先(根)進(jìn)程指針、父進(jìn)程指針、子進(jìn)程鏈指針、兄弟進(jìn)程鏈指針。進(jìn)程的狀態(tài)與調(diào)度信息:如進(jìn)程的當(dāng)前狀態(tài)(執(zhí)行態(tài)、就緒態(tài)、阻塞態(tài)等之一)、相應(yīng)的狀態(tài)隊(duì)列指針(包括隊(duì)首指針和next指針)、以及進(jìn)程優(yōu)先級。存儲映象的指針與大小:存儲映象在內(nèi)存和虛存的指針和大小。現(xiàn)場保留區(qū):存放進(jìn)程被阻塞或被中斷時的現(xiàn)場(上下文)信息,即CPU中各寄存器的值,包括PSW

12、寄存器的值。21進(jìn)程通信信息:如信號量(燈)、消息隊(duì)列指針、信箱指針句柄、接收到的信號等。所用資源信息:如打開文件的句柄(描述字)。PCB需占用較大的空間,UNIX將PCB分成兩個部分:常駐內(nèi)存部分稱為proc結(jié)構(gòu),非常駐內(nèi)存部分為user結(jié)構(gòu)。Linux的PCB則稱為task_struct。通常,操作系統(tǒng)在內(nèi)核存儲區(qū)中開辟一個線性的PCB表,該表的每個元素就是一個PCB,表長為系統(tǒng)允許存在的最大進(jìn)程數(shù)(Linux默認(rèn)為512)。在創(chuàng)建一個新進(jìn)程時,首先要從PCB表中找尋一個空閑PCB,用它來創(chuàng)建新進(jìn)程。有些系統(tǒng)也用鏈表形式組織PCB。22Linux采用哈希表方法來組織PCB表。進(jìn)程創(chuàng)建時被分

13、配有一個唯一的PID,用它計(jì)算出的哈希值就是該進(jìn)程的PCB在PCB表中的位置。為了方便管理,通常把處于各種不同狀態(tài)的進(jìn)程鏈接成不同的隊(duì)列。進(jìn)程隊(duì)列實(shí)際就是PCB隊(duì)列。對于單CPU系統(tǒng),通常設(shè)置有:一個執(zhí)行隊(duì)列(只有一個隊(duì)列元素)。一個多個就緒隊(duì)列(按優(yōu)先級別范圍設(shè)置)若干阻塞隊(duì)列(每種阻塞事件對應(yīng)一個阻塞隊(duì)列)。系統(tǒng)為每個隊(duì)列設(shè)置一個全局變量的隊(duì)頭指針Head。在PCB中設(shè)置有隊(duì)列鏈接指針。 231.4 進(jìn)程家族 系統(tǒng)中所有獨(dú)立的活動都可以構(gòu)成一個進(jìn)程。在批處理系統(tǒng)中,系統(tǒng)為每個用戶作業(yè)創(chuàng)建一個用戶作業(yè)進(jìn)程;在交互式系統(tǒng)中,系統(tǒng)為每個登錄的用戶創(chuàng)建一個登錄用戶進(jìn)程。一個用戶進(jìn)程還可以為它的相對

14、獨(dú)立的子任務(wù)創(chuàng)建子進(jìn)程。子進(jìn)程可以繼承父進(jìn)程的全部或部分資源并和父進(jìn)程并發(fā)執(zhí)行。父與子的概念是相對的,子進(jìn)程又可以創(chuàng)建自己的子進(jìn)程,構(gòu)成新的父子關(guān)系。一個進(jìn)程還可以創(chuàng)建多個平行的子進(jìn)程。于是,多層次的父子關(guān)系便形成了一個樹結(jié)構(gòu)(倒掛樹)的進(jìn)程家族。在進(jìn)程樹中,樹的頂節(jié)點(diǎn)是進(jìn)程家族中所有進(jìn)程的祖先(根),它最先被創(chuàng)建,最后被撤消。顯然,一個進(jìn)程可以有多個子孫進(jìn)程,但每個進(jìn)程只有一個父進(jìn)程(除根進(jìn)程外)。對于一個進(jìn)程家族,當(dāng)其根進(jìn)程被撤消后,整個進(jìn)程家族亦就隨之消亡。24一個用戶進(jìn)程家族是隨著某個用戶作業(yè)的啟動或交互用戶登錄成功而動態(tài)產(chǎn)生并隨著進(jìn)展而動態(tài)形成,隨著用戶作業(yè)的終止或用戶退出系統(tǒng)而動態(tài)

15、消亡。系統(tǒng)進(jìn)程的產(chǎn)生與消亡是與用戶進(jìn)程不同的。在系統(tǒng)初啟時,首先創(chuàng)建一個系統(tǒng)總控進(jìn)程系統(tǒng)根進(jìn)程(如UNIX的0#進(jìn)程,Linux的init進(jìn)程),再由該系統(tǒng)根進(jìn)程創(chuàng)建其他系統(tǒng)服務(wù)進(jìn)程,這些系統(tǒng)服務(wù)進(jìn)程之間的關(guān)系是平等的,不存在隸屬關(guān)系和資源繼承關(guān)系,而且系統(tǒng)服務(wù)進(jìn)程一旦被創(chuàng)建便永無休止地參與并發(fā)運(yùn)行,為所有用戶進(jìn)程提供服務(wù),直至系統(tǒng)終止時,由系統(tǒng)總控進(jìn)程撤消所有系統(tǒng)服務(wù)進(jìn)程,并最終自行消亡。252 進(jìn)程服務(wù)創(chuàng)建系統(tǒng)調(diào)用阻塞系統(tǒng)調(diào)用喚醒系統(tǒng)調(diào)用撤消系統(tǒng)調(diào)用26進(jìn)程服務(wù)是現(xiàn)代操作系統(tǒng)向用戶和用戶程序提供的一項(xiàng)重要且必不可少的服務(wù)功能,包括:創(chuàng)建、阻塞、喚醒、終止、撤消、查詢等。執(zhí)行這些服務(wù)功能的是

16、內(nèi)核函數(shù)。用戶進(jìn)程可通過兩種方式來訪問這些內(nèi)核函數(shù):在提供進(jìn)程服務(wù)器的系統(tǒng)上,用戶進(jìn)程可通過進(jìn)程服務(wù)器獲得相應(yīng)服務(wù);而在一些系統(tǒng)上,用戶進(jìn)程可直接通過系統(tǒng)調(diào)用的方式來訪問這些內(nèi)核函數(shù)。習(xí)慣上也把這些內(nèi)核服務(wù)函數(shù)稱為系統(tǒng)調(diào)用函數(shù)或直稱系統(tǒng)調(diào)用。此外,用戶可使用shell命令請求某些進(jìn)程服務(wù)。272.1 “創(chuàng)建”系統(tǒng)調(diào)用一個進(jìn)程可以將一項(xiàng)相對獨(dú)立的任務(wù)交由一個子進(jìn)程來完成,它可通過系統(tǒng)調(diào)用“創(chuàng)建”來創(chuàng)建其子進(jìn)程,創(chuàng)建后,父子進(jìn)程可并發(fā)執(zhí)行。1. 創(chuàng)建進(jìn)程算法創(chuàng)建進(jìn)程的一般算法是:為新進(jìn)程分配一個唯一的PID和一個空閑的PCB;為進(jìn)程映象分配內(nèi)存空間;將進(jìn)程正文(可執(zhí)行程序)從磁盤讀入內(nèi)存;初始化P

17、CB及其他映象;將PCB插入就緒隊(duì)列。系統(tǒng)調(diào)用返回28Windows操作系統(tǒng)的創(chuàng)建算法基本同上,提供的相應(yīng)系統(tǒng)調(diào)用是CreateProcess。UNIXLinux所采用的算法則有所不同,它提供了兩個系統(tǒng)調(diào)用:fork和exec。2. fork系統(tǒng)調(diào)用fork很有特色,它采用“克隆”(clone)的方法,創(chuàng)建一個與當(dāng)前進(jìn)程(新進(jìn)程的父進(jìn)程)的運(yùn)行配置完全一樣的子進(jìn)程。fork很復(fù)雜,大致完成以下操作:29(1)為新進(jìn)程分配一個PID和PCBfork首先檢查系統(tǒng)是否有足夠的內(nèi)存資源來建立一個新進(jìn)程以及系統(tǒng)中的進(jìn)程數(shù)是否已超限。如果資源不足或進(jìn)程數(shù)超限,則返回-1,表示創(chuàng)建失敗;否則,為新進(jìn)程分配一

18、個唯一的PID和一個空閑的PCB,該P(yáng)ID其實(shí)就是其PCB在PCB表中的索引號。(2)復(fù)制PCB并初始化復(fù)制一個父進(jìn)程的PCB副本到子進(jìn)程的PCB中,然后把其中的PID的值改為新進(jìn)程的PID,當(dāng)前進(jìn)程置為子進(jìn)程的父進(jìn)程,以及其他必要的初始化工作。所以,子進(jìn)程擁有與父進(jìn)程一樣的UID、GID、優(yōu)先數(shù)值、當(dāng)前目錄、用戶文件描述符表等。30(3)共享父進(jìn)程的所有文件資源把與父進(jìn)程相連的文件表和索引節(jié)點(diǎn)表的引用計(jì)數(shù)器加1。這些文件自動地與子進(jìn)程相連。(4)創(chuàng)建子進(jìn)程的內(nèi)存實(shí)體按父進(jìn)程的數(shù)據(jù)段和棧段的大小為新進(jìn)程分配內(nèi)存空間,并復(fù)制父進(jìn)程的數(shù)據(jù)段和棧段的內(nèi)容,同時修改新進(jìn)程PCB中的相應(yīng)指針。(注意:新

19、進(jìn)程完全共享父進(jìn)程的正文段) (5)給新進(jìn)程返回0,給父進(jìn)程返回新進(jìn)程的PID。31由上可知,當(dāng)一個子進(jìn)程剛被創(chuàng)建時,它與父進(jìn)程共享正文段,且起始執(zhí)行位置相同,雖然有新分配的數(shù)據(jù)段和棧段,但它們的內(nèi)容也與父進(jìn)程的相同。那么兩者以后是否只能執(zhí)行相同的程序代碼和完成相同的功能呢?關(guān)鍵在于上述第5步,fork采用了“一次調(diào)用,分叉(fork)返回兩值”的技術(shù),即它給父進(jìn)程返回子進(jìn)程的PID,給子進(jìn)程返回0(注:fork把返回值分別送入兩個進(jìn)程各自的堆棧中)。由于父子進(jìn)程共享同一程序,所以只要在該程序中的系統(tǒng)調(diào)用的返回點(diǎn)安排一條if 語句,就可以通過判斷返回值使父子進(jìn)程分別執(zhí)行各自代碼。32在父進(jìn)程的

20、執(zhí)行程序中創(chuàng)建“克隆”子進(jìn)程的一般方法:int pid;while(pid=fork()=-1); /*調(diào)用fork創(chuàng)建子進(jìn)程,直到成功*/if(pid=0) /*收到返回值0,執(zhí)行下面的子進(jìn)程代碼*/ exit(0); /*系統(tǒng)調(diào)用exit,子進(jìn)程自行終止*/ else /*收到返回值為子進(jìn)程的pid ,執(zhí)行下面的父進(jìn)程代碼*/ 33其中的系統(tǒng)調(diào)用exit(0)執(zhí)行的功能是:回收調(diào)用者的除了PCB之外的各種內(nèi)存映像,同時把PCB中的進(jìn)程運(yùn)行狀態(tài)置為“僵死(終止)”態(tài),然后向該進(jìn)程的父進(jìn)程發(fā)出“已終止”軟中斷信號。在這種方法中,子進(jìn)程的執(zhí)行代碼嵌入在父進(jìn)程的程序代碼中。顯然,這種方法適合于子進(jìn)

21、程代碼量較少的情況。fork的這種“克隆”式的子進(jìn)程創(chuàng)建方法在很多情況下是很有用的且效率高。例如,Web服務(wù)器在每收到一個用戶請求后,就創(chuàng)建一個新的但一模一樣配置的克隆進(jìn)程來響應(yīng)用戶的服務(wù)請求。而在windows下過程就要更復(fù)雜一些。342. exec系統(tǒng)調(diào)用使用fork創(chuàng)建的是父進(jìn)程的一個克隆子進(jìn)程。如果想創(chuàng)建一個擁有獨(dú)立程序代碼的子進(jìn)程,則可以在調(diào)用了fork后再調(diào)用exec。exec較fork簡單,它完成以下操作:(1)如果新進(jìn)程的程序不在內(nèi)存,則為指定的程序文件分配內(nèi)存空間(正文段),然后將該程序文件從磁盤讀入正文段;否則,與該程序建立共享鏈接。(2)修改新進(jìn)程PCB中的有關(guān)數(shù)據(jù),如正

22、文段的指針和大小、正文段的入口指針、棧指針等。35在父進(jìn)程的程序代碼中創(chuàng)建非克隆子進(jìn)程的一般方法:int pid;while(pid=fork()=-1); /*調(diào)用fork創(chuàng)建子進(jìn)程,直到成功*/if(pid=0) /*收到返回值0 ,執(zhí)行下面的子進(jìn)程代碼*/ exec( pfile, argv); /*調(diào)用exec,加載子進(jìn)程的獨(dú)立程序*/else/*收到返回值為子進(jìn)程的pid ,執(zhí)行下面的父進(jìn)程代碼*/ 362.2 “阻塞“系統(tǒng)調(diào)用當(dāng)現(xiàn)行進(jìn)程需要等待某個事件時,可通過“阻塞“系統(tǒng)調(diào)用阻塞自己。1. 阻塞進(jìn)程算法阻塞的一般算法是:保存現(xiàn)行進(jìn)程的現(xiàn)場;將現(xiàn)行進(jìn)程從執(zhí)行態(tài)切換為阻塞態(tài);將該進(jìn)程

23、加入到相應(yīng)事件的阻塞隊(duì)列中;跳轉(zhuǎn)到進(jìn)程調(diào)度程序執(zhí)行新一輪的進(jìn)程調(diào)度。進(jìn)程調(diào)度程序也是內(nèi)核模塊。 372. Linux的“阻塞”系統(tǒng)調(diào)用Linux提供了2個實(shí)現(xiàn)阻塞功能的系統(tǒng)調(diào)用:wait和sleep。wait()的功能是調(diào)用者等待某個子進(jìn)程的執(zhí)行終止。wait()的算法:(1)首先查找調(diào)用者進(jìn)程是否有子進(jìn)程,若無,則返回出錯碼;(2)如果找到一處于“僵死”(終止)狀態(tài)的子進(jìn)程,則將該子進(jìn)程的執(zhí)行時間加到調(diào)用者(父進(jìn)程)的執(zhí)行時間上,并釋放子進(jìn)程的PCB,即銷毀了該子進(jìn)程;然后立即返回調(diào)用者,調(diào)用者可繼續(xù)執(zhí)行。38(3)如果未找到已“僵死”的子進(jìn)程,則將調(diào)用者置成“睡眠”(即阻塞)狀態(tài),并加入到

24、睡眠隊(duì)列中,等待其子進(jìn)程發(fā)來軟中斷信號時被喚醒。另外,也可以使用wait(pid),其中的參數(shù)pid是某子進(jìn)程的PID,即該wait系統(tǒng)調(diào)用使調(diào)用者進(jìn)程進(jìn)入睡眠,一直到其指定的子進(jìn)程執(zhí)行終止為止。sleep(second)的功能是使調(diào)用者進(jìn)程進(jìn)入睡眠,直到second秒后喚醒。392.3 “喚醒“系統(tǒng)調(diào)用完成或發(fā)現(xiàn)某事件的進(jìn)程可通過“喚醒”系統(tǒng)調(diào)用,喚醒因等待該事件而被阻塞的某個進(jìn)程。1. 喚醒進(jìn)程算法喚醒的一般算法是:從指定事件的阻塞隊(duì)列中找到要喚醒進(jìn)程的PCB;修改PCB中的有關(guān)信息,將該進(jìn)程置為就緒態(tài);將該P(yáng)CB從阻塞隊(duì)列中移出,并插入到就緒隊(duì)列中。系統(tǒng)調(diào)用返回402. Linux的“喚

25、醒”系統(tǒng)調(diào)用Linux提供的“喚醒”系統(tǒng)調(diào)用是wake_up(),它有多種原型,如wake_up、wake_up_all、wake_up_nr、wake_up_locked等。412.4 “撤消“系統(tǒng)調(diào)用父進(jìn)程可通過“撤消”系統(tǒng)調(diào)用來撤消它的子進(jìn)程,包括正常撤消和異常撤消。前者是子進(jìn)程在完成了任務(wù)并報告了父進(jìn)程后實(shí)施的正常撤消;后者則是父進(jìn)程對子進(jìn)程進(jìn)行的強(qiáng)制性撤消(如撤消死鎖態(tài)進(jìn)程)。1. 撤消進(jìn)程算法撤消的一般算法是:從PCB集中找到要撤消子進(jìn)程的PCB;若該子進(jìn)程還有其子進(jìn)程,則遞歸撤消子孫進(jìn)程;回收子進(jìn)程所使用的資源;回收子進(jìn)程的PCB。系統(tǒng)調(diào)用返回422. Linux的“撤消”系統(tǒng)調(diào)

26、用正常情況下,子進(jìn)程使用exit(0)系統(tǒng)調(diào)用終止自己,父進(jìn)程則使用wait()系統(tǒng)調(diào)用撤消其子進(jìn)程。父進(jìn)程還可以使用kill(pid, SIGKILL)系統(tǒng)調(diào)用來強(qiáng)制“殺死”指定的pid子進(jìn)程。433線 程 線程概念線程管理模式線程的困惑44線程(thread)是操作系統(tǒng)領(lǐng)域中較晚出現(xiàn)的一個概念,是繼進(jìn)程之后的又一個關(guān)鍵概念。傳統(tǒng)的操作系統(tǒng)以進(jìn)程為中心,系統(tǒng)的結(jié)構(gòu)、設(shè)計(jì)及執(zhí)行均以進(jìn)程為基礎(chǔ),故通常稱傳統(tǒng)的操作系統(tǒng)為面向進(jìn)程的操作系統(tǒng)模式,簡稱進(jìn)程模式。線程是對進(jìn)程的發(fā)展,線程的引入進(jìn)一步提高了系統(tǒng)的并發(fā)性,并顯著改善了系統(tǒng)的運(yùn)行效率。引入線程的操作系統(tǒng)也被稱之為“進(jìn)程線程模式”,或稱“多線程

27、模式”。當(dāng)前的許多主流操作系統(tǒng)都不同程度地采用了多線程模式,如 UNIX、Linux、Windows、OS/390等。453.1 線程概念 1. 線程的引入傳統(tǒng)的進(jìn)程集兩種重要角色于一身:(1) 進(jìn)程是擁有系統(tǒng)資源的獨(dú)立實(shí)體每個進(jìn)程擁有一個獨(dú)立的地址空間(邏輯地址構(gòu)成的存儲空間),用于存放該進(jìn)程的所有映象。在進(jìn)程運(yùn)行過程中,進(jìn)程還可以動態(tài)獲取CPU、I/O處理器、I/O設(shè)備和文件等資源。進(jìn)程在擁有資源的期間,對這些資源具有控制權(quán),其他進(jìn)程不經(jīng)允許是不能訪問這些資源的。OS對每個進(jìn)程擁有的資源實(shí)施保護(hù)。(2) 進(jìn)程是可被調(diào)度和受配CPU的執(zhí)行實(shí)體每當(dāng)OS需要進(jìn)行CPU分配時,就根據(jù)某種調(diào)度算法從

28、所有就緒進(jìn)程中選擇一個合適的進(jìn)程,把CPU分配給該進(jìn)程使用一個CPU時段。獲得CPU使用權(quán)的進(jìn)程可在46 CPU上執(zhí)行它的程序。這兩種角色是傳統(tǒng)進(jìn)程的本質(zhì)所在,是多道程序并發(fā)運(yùn)行的基礎(chǔ)。但是這種集兩種角色于一身的進(jìn)程也帶來了一些副作用。例如:進(jìn)程是并發(fā)運(yùn)行的,每個進(jìn)程在其執(zhí)行過程中經(jīng)常要被打斷,呈現(xiàn)走走停停的情形。在進(jìn)程模式中,當(dāng)發(fā)生一個中斷時,通常要進(jìn)行進(jìn)程切換,完成一次進(jìn)程切換需要花費(fèi)不少的CPU時間開銷;為提高并發(fā)性以加快進(jìn)程的運(yùn)行速度,每個進(jìn)程都可以為它的某個相對獨(dú)立的子任務(wù)動態(tài)創(chuàng)建子進(jìn)程,子進(jìn)程可與父進(jìn)程并發(fā)運(yùn)行,子進(jìn)程與子進(jìn)程也可并發(fā)運(yùn)行。子進(jìn)程完成其任務(wù)后,可被動態(tài)終止和撤消。但

29、創(chuàng)建和最終撤消一個進(jìn)程同樣需要花費(fèi)不少的CPU開銷。47另外,進(jìn)程之間共享軟資源難以實(shí)現(xiàn)。例如,一進(jìn)程的多個子進(jìn)程需要共享某個變量,顯然只能把該變量作為全局變量定義在父進(jìn)程中,但子進(jìn)程與父進(jìn)程的地址空間是隔離的,即子進(jìn)程是不能直接訪問父進(jìn)程的地址空間的。總之,在進(jìn)程模式中,進(jìn)程切換和進(jìn)程的創(chuàng)建及撤消都需要一定的CPU開銷,如果這些操作比較頻繁的話,那么系統(tǒng)就要為此付出較大的額外CPU開銷,這在一定程度上降低了進(jìn)程并發(fā)運(yùn)行所帶來的好處,影響了系統(tǒng)的有效性。此外,進(jìn)程之間共享軟資源也難以實(shí)現(xiàn)。48為此,操作系統(tǒng)專家們研究如何在支持系統(tǒng)高并發(fā)性的前提下,盡量減少需要付出的額外系統(tǒng)開銷,以改善系統(tǒng)的執(zhí)

30、行效率。基本目標(biāo)是盡量減少進(jìn)程切換和進(jìn)程的創(chuàng)建及撤消的次數(shù)。切入點(diǎn)是進(jìn)程所承擔(dān)的兩種獨(dú)立的角色。專家們設(shè)想,既然傳統(tǒng)進(jìn)程所承擔(dān)的兩種角色是相互獨(dú)立的,那么就可以將它們分離,分別交由兩種不同的實(shí)體來承擔(dān),使僅作為執(zhí)行程序的實(shí)體都能“輕裝”運(yùn)行。于是就引入了“線程”,并獨(dú)立承擔(dān)傳統(tǒng)進(jìn)程的第二種角色,而新的進(jìn)程就只承擔(dān)原先的第一種角色,即引入線程后,雖然仍保留了進(jìn)程,但現(xiàn)在的進(jìn)程主要是系統(tǒng)資源的擁有者,而線程是可被調(diào)度和受配CPU的執(zhí)行實(shí)體。492. 線程與進(jìn)程在“進(jìn)程線程模式”中,進(jìn)程和線程都是系統(tǒng)中可并發(fā)的實(shí)體,但分別承擔(dān)了兩種不同的角色,它們的特性及關(guān)系如下:進(jìn)程是擁有系統(tǒng)資源的獨(dú)立實(shí)體,每個

31、進(jìn)程擁有一個受操作系統(tǒng)保護(hù)的獨(dú)立的進(jìn)程地址空間,進(jìn)程還可以動態(tài)獲取CPU、I/O設(shè)備、文件等資源。線程是進(jìn)程內(nèi)的一種專門負(fù)責(zé)執(zhí)行程序的執(zhí)行實(shí)體,是隸屬于進(jìn)程的相對獨(dú)立實(shí)體。線程利用所屬進(jìn)程所擁有的資源,執(zhí)行該進(jìn)程的程序代碼。作為程序執(zhí)行實(shí)體,線程是物理CPU的實(shí)際受配者。50進(jìn)程為執(zhí)行它的程序任務(wù),可創(chuàng)建一個或多個線程,每個進(jìn)程至少含有一個線程,在創(chuàng)建進(jìn)程時同時創(chuàng)建了該進(jìn)程的第一個線程。一個進(jìn)程擁有的全部資源可供該進(jìn)程內(nèi)的所有線程共享。一個進(jìn)程內(nèi)的所有線程共享該進(jìn)程的正文段和數(shù)據(jù)段,但每個線程都擁有自己的私有映象:線程控制塊(TCB)和棧段。TCB包含了一個線程的專有屬性及其執(zhí)行現(xiàn)場信息。51

32、PCB正文段數(shù)據(jù)段TCB棧段TCB棧段TCB棧段 線程1 線程2 線程n 其中:PCB存放于內(nèi)核空間;正文段和數(shù)據(jù)段以及各線程的棧段存放在進(jìn)程地址空間中;TCB或存放于內(nèi)核空間(內(nèi)核級線程)或存放于進(jìn)程地址空間(用戶級線程)。圖2-2 多線程進(jìn)程的地址空間52一個線程具有生命期,并至少具有三種基本運(yùn)行狀態(tài):就緒、執(zhí)行及阻塞。線程可動態(tài)創(chuàng)建其他線程(隸屬同一進(jìn)程),一個進(jìn)程內(nèi)的所有線程可并發(fā)執(zhí)行。3. 多線程模式的優(yōu)點(diǎn)多線程模式較之進(jìn)程模式的優(yōu)點(diǎn)主要在于顯著改進(jìn)了系統(tǒng)的執(zhí)行效率,提高了系統(tǒng)的并發(fā)性,具體體現(xiàn)在:(1) 線程較之進(jìn)程更為活躍。因此,在進(jìn)程模式中創(chuàng)建和撤消進(jìn)程的工作在進(jìn)程線程模式中大

33、多被轉(zhuǎn)化成線程的創(chuàng)建和撤消,而用于創(chuàng)建和撤消線程的系統(tǒng)開銷要少得多。創(chuàng)建線程時僅需建立TCB和工作棧。而在創(chuàng)建進(jìn)程時要建立PCB,建立進(jìn)程地址空間,裝入進(jìn)程的正文和53數(shù)據(jù)等,這比創(chuàng)建線程時的工作量要大得多,周期要長得多。據(jù)研究表明,創(chuàng)建一個線程的速度比在進(jìn)程模式中創(chuàng)建一個進(jìn)程提高約10倍。(2) 在多線程模式中,進(jìn)程切換的次數(shù)也要大大減少。線程是執(zhí)行程序的實(shí)際實(shí)體,故因CPU切換導(dǎo)致的主要是線程切換。而在同一進(jìn)程中的線程切換所需的系統(tǒng)開銷比進(jìn)程切換要少得多,因?yàn)檫@種線程切換只需切換線程的執(zhí)行現(xiàn)場以及更新相關(guān)的狀態(tài)隊(duì)列,無需進(jìn)行進(jìn)程地址空間的切換,特別是如果為用戶級線程,線程切換時還無需進(jìn)行C

34、PU執(zhí)行狀態(tài)的切換。但當(dāng)線程切換在隸屬不同進(jìn)程的線程之間發(fā)生時仍將導(dǎo)致進(jìn)程切換。 54(3) 多線程模式提高了執(zhí)行實(shí)體之間的通信效率。進(jìn)程之間的通信需要內(nèi)核的支持,由于各進(jìn)程的地址空間是隔離的,故它們相互傳遞的信號或消息需通過內(nèi)核轉(zhuǎn)遞,而內(nèi)核的每次干預(yù)必將引起兩次CPU執(zhí)行狀態(tài)的切換:從用戶態(tài)到核心態(tài),又從核心態(tài)到用戶態(tài)。但在一個進(jìn)程中,并發(fā)線程之間的通信可直接進(jìn)行,無需內(nèi)核的干預(yù),因?yàn)樗鼈児蚕碓撨M(jìn)程的數(shù)據(jù)段和文件。(4)在進(jìn)程模式下,實(shí)現(xiàn)一進(jìn)程的多個子進(jìn)程共享變量很復(fù)雜,難以實(shí)現(xiàn)。而在多線程模式下,由于線程共享其父進(jìn)程的地址空間,故實(shí)現(xiàn)這項(xiàng)功能沒有絲毫問題。(子進(jìn)程是已成年且分家獨(dú)立的孩子,

35、線程是未分家獨(dú)立的孩子。)55在操作系統(tǒng)的各種服務(wù)器進(jìn)程中引入線程可大大提高系統(tǒng)的服務(wù)質(zhì)量。例如Web服務(wù)器,每當(dāng)傳來一個Web服務(wù)請求時, Web服務(wù)器便立即響應(yīng)并創(chuàng)建一個Web服務(wù)線程。一個Web服務(wù)器可同時具有多個Web服務(wù)線程,分別處理不同的服務(wù)請求,它們可并發(fā)執(zhí)行。當(dāng)現(xiàn)行Web服務(wù)線程被阻塞時,可切換到另一個就緒態(tài)線程。因此宏觀上, Web服務(wù)器同時響應(yīng)并處理多個Web服務(wù)請求。如果Web服務(wù)器運(yùn)行在多處理器的機(jī)器上,那么服務(wù)器中的多個線程可被調(diào)度到不同的處理器上并行執(zhí)行。有時也把進(jìn)程模式叫做單線程模式,即進(jìn)程只包含一個線程。563.2 線程管理模式 線程的管理類似于進(jìn)程管理,通常包

36、括如下功能:線程服務(wù),包括:創(chuàng)建、撤消、阻塞、喚醒等線程調(diào)度線程同步線程通信實(shí)現(xiàn)線程管理有兩種基本模式:KLT和ULT 571. ULT(User-level Threads)模式操作系統(tǒng)內(nèi)核自身并不具有線程管理功能,而是借助線程庫為用戶程序提供提供線程機(jī)制。由此產(chǎn)生和運(yùn)行的線程稱之為用戶級線程(ULT)。線程庫是由語言系統(tǒng)(如Java、C)提供的供用戶程序使用的公用軟件包,其中定義了一組用于線程管理的函數(shù)以及相關(guān)的數(shù)據(jù)結(jié)構(gòu)。線程庫被連接(包含)到用戶程序中,作為用戶程序的功能在進(jìn)程的地址空間中執(zhí)行。在用戶程序中可直接利用函數(shù)調(diào)用來訪問線程管理函數(shù),而無需通過系統(tǒng)調(diào)用。線程庫是完全獨(dú)立于內(nèi)核的

37、,內(nèi)核并不知道線程庫和ULT的存在,內(nèi)核既不維護(hù)TCB,也不支持線程調(diào)度,內(nèi)核管理的仍然是進(jìn)程,CPU的調(diào)度和受配對象依然是進(jìn) 58程。線程的實(shí)現(xiàn)和管理實(shí)際上只是用戶程序自身的行為,是用戶程序借助線程庫來實(shí)現(xiàn)的,ULT對操作系統(tǒng)內(nèi)核完全透明。其優(yōu)點(diǎn)如下:實(shí)現(xiàn)簡單。ULT與內(nèi)核無關(guān),不需要修改內(nèi)核,因此便于實(shí)現(xiàn)。便于移植。ULT的創(chuàng)建、調(diào)度和其他管理的算法與內(nèi)核無關(guān),很容易在多個操作系統(tǒng)之間移植。開銷小。因?yàn)椴恍枰獌?nèi)核的干預(yù),線程的創(chuàng)建、切換等開銷小。其缺點(diǎn)如下:一個進(jìn)程的多個線程不能同時執(zhí)行。因?yàn)閮?nèi)核的調(diào)度單位是進(jìn)程,故內(nèi)核只可能給一個進(jìn)程一次分配一個59CPU,即便是在多核(多CPU)系統(tǒng)中

38、。換言之,ULT不能提高進(jìn)程內(nèi)的并發(fā)性。當(dāng)一個線程被阻塞,則整個進(jìn)程被阻塞,即該進(jìn)程的其他所有線程也同時被阻塞。因?yàn)闆]有內(nèi)核干預(yù),有些功能難于實(shí)現(xiàn)。例如,采用動態(tài)優(yōu)先級線程調(diào)度需要知道每個線程的執(zhí)行時間,沒有內(nèi)核干預(yù)很難準(zhǔn)確地得到這樣的信息。602. KLT(Kernel-Level Threads)模式由操作系統(tǒng)內(nèi)核提供并完成所有的線程管理工作,即內(nèi)核中設(shè)計(jì)有完成各種線程管理功能的原語,它們由相關(guān)的系統(tǒng)調(diào)用和中斷所驅(qū)動,在CPU的核心態(tài)下執(zhí)行。由此產(chǎn)生和運(yùn)行的線程稱之為內(nèi)核級線程(KLT)。其優(yōu)點(diǎn)如下:一個進(jìn)程的多個線程可同時執(zhí)行。在KLT模式中,內(nèi)核的調(diào)度單位通常為線程。因此在多處理器系統(tǒng)中,內(nèi)核可將一進(jìn)程的多個線程同時調(diào)度到多個CPU上并行執(zhí)行,從而大大加快進(jìn)程的運(yùn)行速度。一個線程的阻塞不會影響到該進(jìn)程的其他線程。KLT模式的缺點(diǎn)是實(shí)現(xiàn)復(fù)雜,內(nèi)核需要專門的數(shù)據(jù)結(jié)構(gòu)和程序模塊來描述線程。另外,KLT的創(chuàng)建和管理均需要內(nèi)核的干預(yù),因此,和ULT

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論