LINUX內(nèi)核進(jìn)程管理_第1頁(yè)
LINUX內(nèi)核進(jìn)程管理_第2頁(yè)
LINUX內(nèi)核進(jìn)程管理_第3頁(yè)
LINUX內(nèi)核進(jìn)程管理_第4頁(yè)
LINUX內(nèi)核進(jìn)程管理_第5頁(yè)
已閱讀5頁(yè),還剩73頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

1、第2章 Linux內(nèi)核,進(jìn)程管理,本章主要介紹: 進(jìn)程概念 進(jìn)程的組成 進(jìn)程的狀態(tài)和調(diào)度 進(jìn)程間關(guān)系 中斷處理與定時(shí)器 系統(tǒng)調(diào)用 進(jìn)程間通信,1 進(jìn)程概念,20世紀(jì)60年代,進(jìn)程(process)一詞首先在麻省理工學(xué)院的MULTICS和IBM的CTSS/360系統(tǒng)中被引入。 對(duì)進(jìn)程下個(gè)準(zhǔn)確定義不容易,但有必要強(qiáng)調(diào)一下進(jìn)程具有的兩個(gè)重要特性,1. 獨(dú)立性,進(jìn)程是系統(tǒng)中獨(dú)立存在的實(shí)體,它可以擁有自己獨(dú)立的資源,比如文件和設(shè)備描述符等。 在沒(méi)有經(jīng)過(guò)進(jìn)程本身允許的情況下,其他進(jìn)程不能訪(fǎng)問(wèn)到這些資源。這一點(diǎn)上和線(xiàn)程有很大的不同。 線(xiàn)程是共享資源的程序?qū)嶓w,創(chuàng)建一個(gè)線(xiàn)程所花費(fèi)的系統(tǒng)開(kāi)銷(xiāo)要比創(chuàng)建一個(gè)進(jìn)程小得

2、多,一個(gè)程序至少有一個(gè)進(jìn)程,一個(gè)進(jìn)程至少有一個(gè)線(xiàn)程。 線(xiàn)程是進(jìn)程的一個(gè)實(shí)體,是CPU調(diào)度和分派的基本單位,它是比進(jìn)程更小的能獨(dú)立運(yùn)行的基本單位。線(xiàn)程自己基本上不擁有系統(tǒng)資源,只擁有一點(diǎn)在運(yùn)行中必不可少的資源(如程序計(jì)數(shù)器,一組寄存器和棧),但是它可與同屬一個(gè)進(jìn)程的其他的線(xiàn)程共享進(jìn)程所擁有的全部資源,2. 動(dòng)態(tài)性,進(jìn)程與程序的區(qū)別在于,程序只是一個(gè)靜態(tài)的指令集合,而進(jìn)程是一個(gè)正在系統(tǒng)中活動(dòng)的指令集合。 在進(jìn)程中加入了時(shí)間的概念。進(jìn)程具有自己的生命周期和各種不同的狀態(tài),這些概念在程序中都是不具備的,由于以上兩個(gè)性質(zhì),又可以衍生出進(jìn)程的第三個(gè)重要特性,即并發(fā)性。 若干個(gè)進(jìn)程可以在單處理機(jī)狀態(tài)上并發(fā)執(zhí)

3、行。注意并發(fā)性(concurrency)和多處理機(jī)并行(parallel)是兩個(gè)不同的概念,并行指在同一時(shí)刻內(nèi),有多條指令在多個(gè)處理機(jī)上同時(shí)執(zhí)行; 并發(fā)指在同一時(shí)刻內(nèi)可能只有一條指令執(zhí)行,但多個(gè)進(jìn)程的指令被快速輪換執(zhí)行,使得在宏觀(guān)上具有多個(gè)進(jìn)程同時(shí)執(zhí)行的效果,2 進(jìn)程的組成,作為申請(qǐng)系統(tǒng)資源的基本單位,進(jìn)程必須有一個(gè)對(duì)應(yīng)的物理內(nèi)存空間。 而對(duì)這樣的一塊空間,首先要用數(shù)據(jù)結(jié)構(gòu)進(jìn)行描述,才能進(jìn)一步對(duì)之進(jìn)行管理,在Linux中,進(jìn)程以進(jìn)程號(hào)PID(process ID)作為標(biāo)識(shí)。 任何對(duì)進(jìn)程進(jìn)行的操作都要給予其相應(yīng)的PID號(hào)。 每個(gè)進(jìn)程都屬于一個(gè)用戶(hù),進(jìn)程要配備其所屬的用戶(hù)編號(hào)UID。 此外,每個(gè)進(jìn)

4、程都屬于多個(gè)用戶(hù)組,所以進(jìn)程還要配備其歸屬的用戶(hù)組編號(hào)GID的數(shù)組,UID和GID都分4種, UID包括uid,euid,suid和fsuid, GID包括gid,egid,sgid和fsgid。 一般來(lái)說(shuō) uid=euid=fsuid, gid=egid=fsgid,進(jìn)程標(biāo)識(shí): uid和gid是運(yùn)行進(jìn)程的用戶(hù)標(biāo)識(shí)和用戶(hù)組標(biāo)識(shí)。 euid和egid又稱(chēng)為有效的uid和gid。出于系統(tǒng)安全權(quán)限的考慮,運(yùn)行程序時(shí)要檢查euid和egid的合法性。通常,uid等于euid,gid等于egid。有時(shí)候,系統(tǒng)會(huì)賦予一般用戶(hù)暫時(shí)擁有root的uid和gid(作為用戶(hù)進(jìn)程的euid和egid),以便于進(jìn)行運(yùn)

5、作。 suid和sgid是根據(jù)POSIX標(biāo)準(zhǔn)引入的,在系統(tǒng)調(diào)用改變uid和gid時(shí),用于保留真正的uid和gid。 fsuid和fsgid稱(chēng)為文件系統(tǒng)的uid和gid,用于對(duì)文件系統(tǒng)操作時(shí)的合法性檢查,是LINUX獨(dú)特的標(biāo)識(shí)類(lèi)型。它們一般分別和euid和egid一致,但在NFS文件系統(tǒng)中NFS服務(wù)器需要作為一個(gè)特殊的進(jìn)程訪(fǎng)問(wèn)文件,這時(shí)只修改客戶(hù)進(jìn)程的fsuid和fsgid,進(jìn)程運(yùn)行的環(huán)境稱(chēng)為進(jìn)程上下文(context)。 Linux中進(jìn)程的上下文由進(jìn)程控制塊PCB(process control block)、正文段(text segment)、數(shù)據(jù)段(data segment)以及用戶(hù)堆棧(

6、stack)組成,其中: 正文段存放該進(jìn)程的可執(zhí)行代碼; 數(shù)據(jù)段存放進(jìn)程中靜態(tài)產(chǎn)生的數(shù)據(jù)結(jié)構(gòu); PCB包括進(jìn)程的編號(hào)、狀態(tài)、優(yōu)先級(jí)以及正文段和數(shù)據(jù)段中數(shù)據(jù)分布的大概情況,個(gè)稱(chēng)做進(jìn)程表(process table)的鏈表結(jié)構(gòu)將系統(tǒng)中所有的PCB塊聯(lián)系起來(lái),如圖2-1所示,圖 2-1 進(jìn)程的數(shù)據(jù)結(jié)構(gòu),Linux源代碼中也將進(jìn)程稱(chēng)作任務(wù)(Task),Linux上的所有進(jìn)程都是由task_struct結(jié)構(gòu)體來(lái)管理。生成一個(gè)進(jìn)程時(shí)會(huì)產(chǎn)生一個(gè)task_struct結(jié)構(gòu)體,此后通過(guò)task_struct結(jié)構(gòu)來(lái)管理進(jìn)程。當(dāng)然文件也是通過(guò)task_struct結(jié)構(gòu)來(lái)管理。 Linux中的PCB塊又稱(chēng)為task_

7、struct結(jié)構(gòu),在2.4版本內(nèi)核中,每個(gè)task_struct占1680個(gè)字節(jié)。 Linux根據(jù)系統(tǒng)物理內(nèi)存的大小限制已打開(kāi)進(jìn)程的總數(shù)目,系統(tǒng)每次訪(fǎng)問(wèn)一個(gè)進(jìn)程時(shí),內(nèi)核根據(jù)PID在進(jìn)程表中查找相應(yīng)的進(jìn)程PCB塊(具體查找過(guò)程通過(guò)一個(gè)PID的hash表實(shí)現(xiàn)),再通過(guò)PCB塊找到其對(duì)應(yīng)的代碼段與數(shù)據(jù)段,并進(jìn)行操作,3 進(jìn)程的狀態(tài)和調(diào)度,Linux系統(tǒng)信號(hào),信號(hào)主要用于通知進(jìn)程異步事件的發(fā)生。在Linux中可以識(shí)別29種不同的信號(hào),這些信號(hào)中的大部分都有了預(yù)先定義好的意義, 進(jìn)程可以顯式的用kill或killpg系統(tǒng)調(diào)用來(lái)向另一個(gè)進(jìn)程發(fā)信號(hào),進(jìn)程可以通過(guò)提供信號(hào)處理函數(shù)來(lái)取代對(duì)于任意信號(hào)的缺省反應(yīng),

8、這種缺省反應(yīng)一般都是終止進(jìn)程。 信號(hào)發(fā)生時(shí),內(nèi)核中斷當(dāng)前的進(jìn)程,進(jìn)程執(zhí)行處理函數(shù)來(lái)響應(yīng)信號(hào),結(jié)束后恢復(fù)正常的進(jìn)程處理。 信號(hào)有自己的名稱(chēng)和特定的編號(hào),見(jiàn)表3-1所示,3-1 Linux 系統(tǒng)信號(hào),進(jìn)程狀態(tài),進(jìn)程是一個(gè)動(dòng)態(tài)的實(shí)體,故而它是有生命的。 從創(chuàng)建到消亡,是一個(gè)進(jìn)程的整個(gè)生命周期。 在這個(gè)周期中,進(jìn)程可能會(huì)經(jīng)歷各種不同的狀態(tài)。 一般來(lái)說(shuō),所有進(jìn)程都要經(jīng)歷以下3種狀態(tài),就緒(ready)態(tài): 指進(jìn)程已經(jīng)獲得所有所需的其他資源,并正在申請(qǐng)?zhí)幚頇C(jī)資源,準(zhǔn)備開(kāi)始運(yùn)行。 這種情況下,稱(chēng)進(jìn)程處于就緒態(tài),阻塞(blocked)態(tài): 指進(jìn)程因?yàn)樾枰却栀Y源而放棄處理機(jī),或者進(jìn)程本不擁有處理機(jī),且其他

9、資源也沒(méi)有滿(mǎn)足,從而即使得到處理機(jī)資源也不能開(kāi)始運(yùn)行。 這種情況下,稱(chēng)進(jìn)程處于阻塞態(tài)。阻塞狀態(tài)又稱(chēng)休眠狀態(tài)或者等待狀態(tài),運(yùn)行態(tài): 進(jìn)程得到了處理機(jī),并不需要等待其他任何資源,正在執(zhí)行的狀態(tài),稱(chēng)之為運(yùn)行態(tài)。 只有在運(yùn)行態(tài)時(shí),進(jìn)程才可以使用所申請(qǐng)到的資源,內(nèi)核以此感知進(jìn)程的存在 財(cái)產(chǎn)登記卡,記錄著進(jìn)程所占用的各項(xiàng)資源,Task_struct數(shù)據(jù)結(jié)構(gòu),進(jìn)程結(jié)構(gòu),task_struct數(shù)據(jù)結(jié)構(gòu) 進(jìn)程標(biāo)志符PID 進(jìn)程所占的內(nèi)存區(qū)域 相關(guān)文件的文件描述符 安全信息 進(jìn)程環(huán)境 信號(hào)處理 資源安排 同步處理 進(jìn)程狀態(tài),include/Linux/sched.h,task_struct (include/li

10、nux/sch.h,進(jìn)程的地址空間,task_struct中有 struct mm_struct *mm; 內(nèi)存描述符 mm_struct 里面有一個(gè)字段mmp 指向內(nèi)存線(xiàn)形區(qū)鏈表的首部,進(jìn)程的狀態(tài),task_struct 中的state 表示進(jìn)程當(dāng)前的狀態(tài) Linux中的進(jìn)程主要有5個(gè)狀態(tài),圖 2-2 Linux 進(jìn)程狀態(tài)轉(zhuǎn)換,RUNNING: 正在運(yùn)行,或者在就緒隊(duì)列中等待運(yùn)行的進(jìn)程。 也就是上面提到的運(yùn)行態(tài)和就緒態(tài)進(jìn)程的綜合。 一個(gè)進(jìn)程處于RUNNING狀態(tài),并不代表它一定在被執(zhí)行,由于在多任務(wù)系統(tǒng)中,各個(gè)就緒進(jìn)程需要并發(fā)執(zhí)行,所以在某個(gè)特定時(shí)刻,這些處于RUNNING狀態(tài)的進(jìn)程之中,只

11、有一個(gè)能夠得到處理機(jī),而其他進(jìn)程必須在一個(gè)就緒隊(duì)列中等待。 即使是在多處理機(jī)的系統(tǒng)中,Linux也只能同時(shí)讓一個(gè)處理機(jī)執(zhí)行任務(wù),UNINTERRUPTABLE: 不可中斷阻塞狀態(tài)。 處于這種狀態(tài)的進(jìn)程正在等待隊(duì)列中,當(dāng)資源有效時(shí),可由操作系統(tǒng)進(jìn)行喚醒,否則,將一直處于等待狀態(tài),INTERRUPTABLE: 可中斷阻塞狀態(tài)。 與不可中斷阻塞狀態(tài)一樣,處于這種狀態(tài)的進(jìn)程也在等待隊(duì)列中,當(dāng)資源有效時(shí),可以由操作系統(tǒng)進(jìn)行喚醒。 與不可中斷阻塞狀態(tài)有所不同的是,處于此狀態(tài)中的進(jìn)程亦可被其他進(jìn)程的信號(hào)和定時(shí)中斷喚醒,STOPPED: 掛起狀態(tài)。 進(jìn)程被暫停,需要通過(guò)其他進(jìn)程的信號(hào)才能被喚醒。 導(dǎo)致這種狀態(tài)

12、的原因有兩種。 其一是受到了相關(guān)信號(hào)(SIGSTOP、SIGSTP、SIGTTIN 或SIGTTOU)的反應(yīng); 其二是受到父進(jìn)程ptrace調(diào)用的控制,而暫時(shí)將處理機(jī)交給控制進(jìn)程,ZOMBIE: 僵尸狀態(tài)。 表示進(jìn)程結(jié)束但尚未消亡的一種狀態(tài)。 此時(shí)進(jìn)程已經(jīng)結(jié)束運(yùn)行并釋放大部分資源,但尚未釋放進(jìn)程控制塊,進(jìn)程調(diào)度,調(diào)度程序(scheduler)用來(lái)實(shí)現(xiàn)進(jìn)程狀態(tài)之間的轉(zhuǎn)換。 在Linux中,調(diào)度程序由系統(tǒng)調(diào)用schedule()來(lái)完成。 schedule()是一個(gè)怪異的函數(shù),它與一般C語(yǔ)言函數(shù)不同,因?yàn)樗恼{(diào)用和返回不在同一個(gè)進(jìn)程中,用戶(hù)進(jìn)程由fork()系統(tǒng)調(diào)用實(shí)現(xiàn)。用戶(hù)進(jìn)程由do_fork()

13、函數(shù)創(chuàng)建,它也是fork系統(tǒng)調(diào)用的執(zhí)行者。 fork()創(chuàng)建一個(gè)新的進(jìn)程,繼承父進(jìn)程的現(xiàn)有資源,初始化進(jìn)程時(shí)鐘、信號(hào)、時(shí)間等數(shù)據(jù)。 完成子進(jìn)程初始化后,父進(jìn)程將它掛到就緒隊(duì)列,返回子進(jìn)程的PID,進(jìn)程創(chuàng)建時(shí)的狀態(tài)為UNINTERRUPTIBLE,在fork()結(jié)束前被父進(jìn)程喚醒后,變?yōu)镽UNNING。 處于RUNNING狀態(tài)的進(jìn)程被移到就緒隊(duì)列中,在適當(dāng)時(shí)候由schedule()按處理機(jī)調(diào)度算法選中,獲得處理機(jī),獲得處理機(jī)而正在運(yùn)行的進(jìn)程若申請(qǐng)不到某個(gè)資源,則調(diào)用sleep()進(jìn)行休眠,其PCB掛到相應(yīng)的等待隊(duì)列,狀態(tài)變?yōu)閁NINTERRUPTIBLE或者INTERRUPTIBLE。 slee

14、p()將調(diào)用schedule()函數(shù)把休眠進(jìn)程釋放的處理機(jī)分配給就緒隊(duì)列中的某個(gè)進(jìn)程,狀態(tài)為INTERRUPTIBLE的休眠進(jìn)程當(dāng)它申請(qǐng)的資源有效時(shí)被喚醒,也可以由信號(hào)或定時(shí)中斷喚醒。 而狀態(tài)為UNINTERRUPTIBLE的休眠進(jìn)程只有當(dāng)它申請(qǐng)的資源有效時(shí)被喚醒,不能被信號(hào)和定時(shí)中斷喚醒。 喚醒后,進(jìn)程狀態(tài)改為RUNNING,并進(jìn)入就緒隊(duì)列,進(jìn)程執(zhí)行系統(tǒng)調(diào)用exit()或收到外部的殺死進(jìn)程信號(hào)SIG_KILL時(shí),進(jìn)程狀態(tài)變?yōu)閆OMBIE,釋放所申請(qǐng)資源。 同時(shí)啟動(dòng)schedule()把處理機(jī)分配給就緒隊(duì)列中其他進(jìn)程,若進(jìn)程通過(guò)系統(tǒng)調(diào)用設(shè)置了跟蹤標(biāo)志位,則在系統(tǒng)調(diào)用返回前,進(jìn)入跟蹤狀態(tài),進(jìn)程狀

15、態(tài)變?yōu)镾TOPPED,處理機(jī)分配給就緒隊(duì)列中其他進(jìn)程。 只有通過(guò)其他進(jìn)程發(fā)送SIG_KILL信號(hào)或繼續(xù)信號(hào)SIG_CONT,才能把STOPPED進(jìn)程喚醒。重新進(jìn)入就緒隊(duì)列,對(duì)每一個(gè)進(jìn)程,其PCB塊中都可以記錄一種調(diào)度策略。 進(jìn)程調(diào)度算法可采用先進(jìn)先出算法(FIFO)或輪轉(zhuǎn)法(round-robin),有實(shí)時(shí)(這里的“實(shí)時(shí)”,只是一種說(shuō)法。實(shí)際上,未經(jīng)改造的Linux很難實(shí)現(xiàn)“實(shí)時(shí)”)和非實(shí)時(shí)兩種形式,若采用Linux的輪轉(zhuǎn)法,當(dāng)時(shí)間片到時(shí)(10ms的整數(shù)倍),由時(shí)鐘中斷觸發(fā),引起新一輪調(diào)度,把當(dāng)前進(jìn)程掛到就緒隊(duì)列隊(duì)尾。 在schedule()中有一個(gè)goodness()函數(shù),可以用來(lái)保證實(shí)時(shí)的

16、進(jìn)程可以得到優(yōu)先調(diào)用。 然而這只是在調(diào)用上優(yōu)先,事實(shí)上在內(nèi)核態(tài)下,實(shí)時(shí)進(jìn)程并不能對(duì)普通進(jìn)程進(jìn)行搶占。 所以L(fǎng)inux中的實(shí)時(shí)并不是真正意義上的實(shí)時(shí),4 進(jìn)程間關(guān)系,Linux中除了0號(hào)進(jìn)程是啟動(dòng)時(shí)由系統(tǒng)創(chuàng)建,其余進(jìn)程都是由其他進(jìn)程自行創(chuàng)建的。為了表示這種創(chuàng)建關(guān)系,用父進(jìn)程指代締造者,用子進(jìn)程指代被創(chuàng)建出的新進(jìn)程。如果進(jìn)程A是進(jìn)程B的間接父進(jìn)程,則A稱(chēng)做B的祖先,B為A的后代。 既然提到了父子關(guān)系,那么這兩個(gè)進(jìn)程之間自然是有著如同父子一樣的繼承性,進(jìn)程的“宗族”關(guān)系 樹(shù)型組織 task_struct中的 struct task_struct *p_pptr, *p_cptr, *p_ysptr,

17、 *p_osptr; p_pptr: parent (父進(jìn)程) p_cptr: child (指向自己最年輕、最新的子進(jìn)程) p_ysptr:指向比自己年輕的兄弟進(jìn)程 p_osptr:指向比自己老的兄弟進(jìn)程,在數(shù)據(jù)結(jié)構(gòu)上,父進(jìn)程PCB中的指針p_cptr指向最近創(chuàng)建的一個(gè)子進(jìn)程的PCB塊,而每個(gè)子進(jìn)程PCB中的指針p_pptr都指向其父進(jìn)程的PCB塊。 這一對(duì)指針構(gòu)成了進(jìn)程的父子關(guān)系,如圖2-3所示,圖 2-3 父子進(jìn)程關(guān)系,除了最老的子進(jìn)程外,每個(gè)子進(jìn)程PCB塊中的p_osptr 指針都指向其父進(jìn)程創(chuàng)建的上一個(gè)子進(jìn)程PCB。 除了最新的子進(jìn)程外,每個(gè)子進(jìn)程PCB塊中的p_ysptr都指向其父

18、進(jìn)程所創(chuàng)建的后一個(gè)子進(jìn)程PCB。 同一個(gè)父親的子進(jìn)程們就按“年齡”順序構(gòu)成了一個(gè)雙向鏈表。 父進(jìn)程則可以通過(guò)其p_cptr指針,從最新創(chuàng)建的子進(jìn)程開(kāi)始,依次訪(fǎng)問(wèn)到其每一個(gè)子進(jìn)程,task數(shù)組(實(shí)際是雙向鏈表指針) 包含指向系統(tǒng)中所有task_struct結(jié)構(gòu)的指針 數(shù)組大小限制了系統(tǒng)中的進(jìn)程數(shù)目 將所有任務(wù)串連起來(lái) Pid hash表 通過(guò)pid查找進(jìn)程時(shí),利用hash快速定位雙向指針 run_list 動(dòng)態(tài)的將任務(wù)鏈入prio_array中的某個(gè)優(yōu)先級(jí)隊(duì)列中,current指針 當(dāng)前運(yùn)行的進(jìn)程的結(jié)構(gòu)用current指針表示 init進(jìn)程 系統(tǒng)初始化后,建立的第一個(gè)進(jìn)程 第一個(gè)task_str

19、uct: INIT_TASK,系統(tǒng)啟動(dòng)時(shí),內(nèi)核被加載到內(nèi)存后,由start_kernel函數(shù)(完成內(nèi)核初始化工作)從無(wú)到有地自行創(chuàng)建了一個(gè)內(nèi)核進(jìn)程,叫做0號(hào)進(jìn)程,其所運(yùn)行的代碼是init_task()函數(shù),在很多鏈表中起表頭的作用。只有當(dāng)沒(méi)有其他進(jìn)程處于可運(yùn)行狀態(tài)時(shí),調(diào)度程序才選擇0號(hào)進(jìn)程。 該進(jìn)程的作用是作為一切其他進(jìn)程的父進(jìn)程,就像亞當(dāng)夏娃是一切人類(lèi)的祖先那樣。 0號(hào)進(jìn)程不能自動(dòng)生成,必須手工將其設(shè)置到進(jìn)程表中去,才能啟動(dòng)進(jìn)程管理機(jī)制,在啟動(dòng)進(jìn)程管理機(jī)制以后,就可以由進(jìn)程自行創(chuàng)建新的子進(jìn)程。 創(chuàng)建新進(jìn)程的調(diào)用是fork()。fork一詞在英文中是“分叉”的意思。 同樣,在Linux中,fo

20、rk()調(diào)用也起了一個(gè)“分叉”的作用。 當(dāng)進(jìn)程A調(diào)用fork()生成進(jìn)程B時(shí),fork()函數(shù)同時(shí)在A和B兩個(gè)進(jìn)程中返回。 其中,父進(jìn)程A里的fork()返回了子進(jìn)程的PID,而子進(jìn)程B里的fork()返回0。如果出現(xiàn)錯(cuò)誤,fork()返回一具負(fù)值,然而,fork()函數(shù)究竟做了些什么呢? 我們發(fā)現(xiàn),經(jīng)過(guò)fork()以后,父進(jìn)程和子進(jìn)程擁有相同內(nèi)容的代碼段、數(shù)據(jù)段和用戶(hù)堆棧,就像父進(jìn)程把自己克隆了一遍。 事實(shí)上,父進(jìn)程只復(fù)制了自己的PCB塊,而代碼段、數(shù)據(jù)段、用戶(hù)堆棧內(nèi)存空間并沒(méi)有復(fù)制一份,而是與子進(jìn)程共享,fork函數(shù)演示見(jiàn)文件fork.swf,從概念上講,fork()就像細(xì)胞的裂變,調(diào)用f

21、ork()的進(jìn)程就是父進(jìn)程,而新裂變出的進(jìn)程就是子進(jìn)程。新創(chuàng)建的進(jìn)程與父進(jìn)程幾乎完全相同,只有少量屬性必須不同。例,每個(gè)進(jìn)程的PID必須是唯一的,調(diào)用fork()后,子進(jìn)程被創(chuàng)建,此時(shí)父進(jìn)程和子進(jìn)程都從這個(gè)系統(tǒng)調(diào)用內(nèi)部繼續(xù)運(yùn)行。為了區(qū)分父子進(jìn)程,fork()給兩個(gè)進(jìn)程返回不同的值。對(duì)父進(jìn)程,fork()返回新創(chuàng)建子進(jìn)程的進(jìn)程標(biāo)識(shí)符(PID),而對(duì)子進(jìn)程,fork()返回值0,只有當(dāng)子進(jìn)程在運(yùn)行中出現(xiàn)寫(xiě)操作時(shí),才會(huì)產(chǎn)生中斷,并為子進(jìn)程分配內(nèi)存空間。 由于父進(jìn)程的PCB和子進(jìn)程的一樣,所以在PCB中所記錄的父進(jìn)程占有的資源,也是與子進(jìn)程共享使用的。 這里的“共享”一詞就意味著“競(jìng)爭(zhēng),有時(shí)候?yàn)榱吮苊?/p>

22、父進(jìn)程和子進(jìn)程競(jìng)爭(zhēng)相同的資源或者出于代碼串行性考慮,我們希望父進(jìn)程可以等待子進(jìn)程運(yùn)行結(jié)束后再繼續(xù)執(zhí)行。 調(diào)用vfork()可以使在子進(jìn)程創(chuàng)建后,隨即向父進(jìn)程發(fā)送SIG_STOP信號(hào),使父進(jìn)程進(jìn)入掛起狀態(tài),直到子進(jìn)程發(fā)送信號(hào)表示其已經(jīng)結(jié)束為止,如果系統(tǒng)中只提供fork()調(diào)用,那么整個(gè)操作系統(tǒng)的所有進(jìn)程就都只能運(yùn)行同一個(gè)程序了,因?yàn)槠浯a段都是復(fù)制或者共享的。 Linux為了創(chuàng)建進(jìn)程運(yùn)行新的程序,采用fork+exec方法。 execve()支持在新的進(jìn)程創(chuàng)建后,動(dòng)態(tài)裝入新的可執(zhí)行文件作為自己新的代碼段。 并且execve()支持多種可執(zhí)行文件的格式,5 進(jìn)程間通訊,用戶(hù)態(tài)進(jìn)程間處于并發(fā)狀態(tài)。

23、為了協(xié)調(diào)進(jìn)程的運(yùn)行,需要實(shí)現(xiàn)進(jìn)程之間通信的機(jī)制,在Linux中,進(jìn)程間通信有以下幾種方法,1.管道機(jī)制 該機(jī)制最適用于解決生產(chǎn)者消費(fèi)者問(wèn)題。 管道是一種在進(jìn)程之間單向流動(dòng)數(shù)據(jù)的結(jié)構(gòu)。 源進(jìn)程向管道寫(xiě)數(shù)據(jù),而內(nèi)核會(huì)自動(dòng)將這些數(shù)據(jù)引導(dǎo)向目標(biāo)進(jìn)程。 在POSIX標(biāo)準(zhǔn)中,管道必須是單向的,雖然通過(guò)pipe()調(diào)用會(huì)產(chǎn)生兩個(gè)描述符(寫(xiě)管道和讀管道),但是在寫(xiě)之前必須關(guān)閉讀管道,反之亦然。 而在Linux中,使用一個(gè)管道的同時(shí)還可以使用另一個(gè)管道,這就大大增強(qiáng)了管道使用的簡(jiǎn)便性,2. 先進(jìn)先出(FIFO)機(jī)制 管道機(jī)制的最大缺點(diǎn)是不能由多個(gè)進(jìn)程共享,除非此管道為這些進(jìn)程共同的祖先所創(chuàng)建。 為了解決這個(gè)問(wèn)題

24、,Linux中引入了FIFO機(jī)制(又稱(chēng)為named pipe,命名管道,FIFO為“first in,first out”的簡(jiǎn)寫(xiě),指一個(gè)在磁盤(pán)上的文件,它可以被所有進(jìn)程所共享。 但是FIFO與一般文件不同,它還使用了內(nèi)核中的緩沖區(qū),所以在效率上要比一般共享文件快得多。 FIFO和管道都可以使用read()和write()調(diào)用來(lái)進(jìn)行讀寫(xiě)操作,3. IPC機(jī)制 IPC是“interprocess communication”的縮寫(xiě)形式。 它包含了一系列系統(tǒng)調(diào)用,允許用戶(hù)態(tài)進(jìn)程通過(guò)信號(hào)量進(jìn)行同步,向其他進(jìn)程發(fā)消息,并且可以與其他進(jìn)程共享一塊內(nèi)存空間. IPC首先是在一個(gè)叫做“Columbus Uni

25、x”的系統(tǒng)中實(shí)現(xiàn)的,其后在現(xiàn)代Unix類(lèi)操作系統(tǒng)中廣為流行,如上文所述,IPC資源包括信號(hào)量,消息隊(duì)列和共享內(nèi)存幾種,1) 消息隊(duì)列,消息隊(duì)列是由內(nèi)核創(chuàng)建并維護(hù)的一個(gè)數(shù)據(jù)結(jié)構(gòu),它是有標(biāo)識(shí)的。 任何具有足夠權(quán)限的進(jìn)程都可以向消息隊(duì)列中放置一個(gè)消息,同樣,任何具有足夠權(quán)限的進(jìn)程都可以從中讀取一個(gè)消息。 這樣,不同的進(jìn)程通過(guò)訪(fǎng)問(wèn)相同的消息隊(duì)列便可實(shí)現(xiàn)進(jìn)程間通信,2) 共享內(nèi)存,共享內(nèi)存區(qū)是這幾種進(jìn)程間通信方式中最快的一種。 它的特點(diǎn)除了速度快外,而且可傳遞的信息量大。 它是通過(guò)將一段內(nèi)存區(qū)映射到一個(gè)進(jìn)程的地址空間來(lái)實(shí)現(xiàn),因此,這種進(jìn)程間通信就不再涉及到內(nèi)核(即進(jìn)程不是通過(guò)執(zhí)行任何進(jìn)入內(nèi)核的系統(tǒng)調(diào)用來(lái)傳遞數(shù)據(jù)的。 這樣,內(nèi)核必須建立允許各個(gè)進(jìn)程共享該內(nèi)存區(qū)的內(nèi)存映射關(guān)系,然后一直管理該內(nèi)存區(qū))。 但同時(shí),也要有效地保證它能同步、有序且沒(méi)有死鎖,用共享內(nèi)存實(shí)現(xiàn)過(guò)程如下,服務(wù)器取得訪(fǎng)問(wèn)該共享內(nèi)存區(qū)的權(quán)限。 服務(wù)器從輸入文件讀取數(shù)據(jù)到該共享內(nèi)存區(qū)。 服務(wù)器讀入數(shù)據(jù)完畢時(shí),通知用戶(hù)進(jìn)程。 用戶(hù)從該共享內(nèi)存區(qū)讀出這些數(shù)據(jù)并輸出,3) 信號(hào)量,信號(hào)量并不是一種IPC機(jī)制,

溫馨提示

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

評(píng)論

0/150

提交評(píng)論