進(jìn)程間通訊機(jī)制_第1頁
進(jìn)程間通訊機(jī)制_第2頁
進(jìn)程間通訊機(jī)制_第3頁
進(jìn)程間通訊機(jī)制_第4頁
進(jìn)程間通訊機(jī)制_第5頁
已閱讀5頁,還剩5頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

1、進(jìn)程間通訊機(jī)制進(jìn)程在核心的協(xié)調(diào)下進(jìn)行相互間的通訊。 Linux 支持大量進(jìn)程間通訊 (IPC) 機(jī)制。除了信號(hào)和管道外,Linux還支持Unix系統(tǒng)V中的IPC機(jī)制。信號(hào)是 Unix 系統(tǒng)中的最古老的進(jìn)程間通訊方式。它們用來向一個(gè)或多個(gè)進(jìn)程發(fā) 送異步事件信號(hào)。 信號(hào)可以從鍵盤中斷中產(chǎn)生, 另外進(jìn)程對(duì)虛擬內(nèi)存的非法存取 等系統(tǒng)錯(cuò)誤環(huán)境下也會(huì)有信號(hào)產(chǎn)生。 信號(hào)還被 shell 程序用來向其子進(jìn)程發(fā)送任 務(wù)控制命令。系統(tǒng)中有一組被詳細(xì)定義的信號(hào)類型, 這些信號(hào)可以由核心或者系統(tǒng)中其它具有 適當(dāng)權(quán)限的進(jìn)程產(chǎn)生。使用kill命令(kill -I)可以列出系統(tǒng)中所有已經(jīng)定義的 信號(hào)。在我的系統(tǒng) (Inte

2、l 系統(tǒng))上運(yùn)行結(jié)果如下:1) SIGHUP2) SIGINT3) SIGQUIT4) SIGILL5) SIGTRAP6) SIGIOT7) SIGBUS8) SIGFPE9) SIGKILL10) SIGUSR111) SIGSEGV12) SIGUSR213) SIGPIPE14) SIGALRM15) SIGTERM17) SIGCHLD18) SIGCONT19) SIGSTOP20) SIGTSTP21) SIGTTIN22) SIGTTOU23) SIGURG24) SIGXCPU25) SIGXFSZ26) SIGVTALRM27) SIGPROF28) SIGWINCH29)

3、 SIGIO30) SIGPWR當(dāng)我在Alpha AXP中運(yùn)行此命令時(shí),得到了不同的信號(hào)個(gè)數(shù)。除了兩個(gè)信號(hào)外, 進(jìn)程可以忽略這些信號(hào)中的絕大部分。其一是引起進(jìn)程終止執(zhí)行的SIGSTOP言號(hào), 另一個(gè)是引起進(jìn)程退出的SIGKILL信號(hào)。至于其它信號(hào),進(jìn)程可以選擇處理它 們的具體方式。 進(jìn)程可以阻塞信號(hào), 如若不阻塞, 則可以在自行處理此信號(hào)和將 其轉(zhuǎn)交核心處理之間作出選擇。 如果由核心來處理此信號(hào), 它將使用對(duì)應(yīng)此信號(hào) 的缺省處理方法。 比如當(dāng)進(jìn)程接收到SIGFPE浮點(diǎn)數(shù)異常)時(shí),核心的缺省操作 是引起core dump和進(jìn)程的退出。信號(hào)沒有固有的相對(duì)優(yōu)先級(jí)。如果在同一時(shí)刻 對(duì)于一個(gè)進(jìn)程產(chǎn)生了兩

4、個(gè)信號(hào),則它們將可能以任意順序到達(dá)進(jìn)程并進(jìn)行處理。同時(shí) Linux 并不提供處理多個(gè)相同類型信號(hào)的方式。 即進(jìn)程無法區(qū)分它是收到了1個(gè)還是42個(gè)SIGCON信號(hào)。Linux 通過存儲(chǔ)在進(jìn)程 task_struct 中的信息來實(shí)現(xiàn)信號(hào)。 信號(hào)個(gè)數(shù)受到處理器 字長(zhǎng)的限制。 32位字長(zhǎng)的處理器最多可以有 32個(gè)信號(hào)而 64位處理器如 Alpha AXP 可以有最多 64 個(gè)信號(hào)。當(dāng)前未處理的信號(hào)保存在 signal 域中,并帶有保存在 blocked中的被阻塞信號(hào)的屏蔽碼。除了 SIGSTO味口 SIGKILL外,所有的信號(hào)都 能被阻塞。 當(dāng)產(chǎn)生可阻塞信號(hào)時(shí), 此信號(hào)可以保持一直處于待處理狀態(tài)直到阻

5、塞 釋放。 Linux 保存著每個(gè)進(jìn)程處理每個(gè)可能信號(hào)的信息,它們保存在每個(gè)進(jìn)程 task_struct 中的 sigaction 數(shù)組中。 這些信息包括進(jìn)程希望處理的信號(hào)所對(duì)應(yīng) 的過程地址,或者指示是忽略信號(hào)還是由核心來處理它的標(biāo)記。通過系統(tǒng)調(diào)用, 進(jìn)程可以修改缺省的信號(hào)處理過程, 這將改變某個(gè)信號(hào)的 sigaction 以及阻塞屏 蔽碼。并不是系統(tǒng)中每個(gè)進(jìn)程都可以向所有其它進(jìn)程發(fā)送信號(hào): 只有核心和超級(jí)用戶具 有此權(quán)限。普通進(jìn)程只能向具有相同 uid 和 gid 的進(jìn)程或者在同一進(jìn)程組中的進(jìn) 程發(fā)送信號(hào)。信號(hào)是通過設(shè)置 task_struct 結(jié)構(gòu)中 signal 域里的某一位來產(chǎn)生 的。

6、如果進(jìn)程沒有阻塞信號(hào)并且處于可中斷的等待狀態(tài),則可以將其狀態(tài)改成 Running,同時(shí)如確認(rèn)進(jìn)程還處在運(yùn)行隊(duì)列中,就可以通過信號(hào)喚醒它。這樣系 統(tǒng)下次發(fā)生調(diào)度時(shí), 調(diào)度管理器將選擇它運(yùn)行。 如果進(jìn)程需要缺省的信號(hào)處理過 程,則Linux可以優(yōu)化對(duì)此信號(hào)的處理。例如 SIGWINCHX窗口的焦點(diǎn)改變)信 號(hào),其缺省處理過程是什么也不做。信號(hào)并非一產(chǎn)生就立刻交給進(jìn)程,而是必須等待到進(jìn)程再次運(yùn)行時(shí)才交給進(jìn)程。 每次進(jìn)程從系統(tǒng)調(diào)用中退出前,它都會(huì)檢查 signal 和 blocked 域,看是否有可 以立刻發(fā)送的非阻塞信號(hào)。 這看起來非常不可靠, 但是系統(tǒng)中每個(gè)進(jìn)程都在不停 地進(jìn)行系統(tǒng)調(diào)用, 如向終端

7、輸出字符。 當(dāng)然進(jìn)程可以選擇去等待信號(hào), 此時(shí)進(jìn)程 將一直處于可中斷狀態(tài)直到信號(hào)出現(xiàn)。對(duì)當(dāng)前不可阻塞信號(hào)的處理代碼放置在 sigaction 結(jié)構(gòu)中。如果信號(hào)的處理過程被設(shè)置成缺省則由核心來應(yīng)付它。SIGSTOP言號(hào)的缺省處理過程是將當(dāng)前進(jìn)程的狀態(tài)改變成為 Stopped 并運(yùn)行調(diào)度管理器以選擇一個(gè)新進(jìn) 程繼續(xù)運(yùn)行。SIGFPE勺缺省處理過程則是引起core dump并使進(jìn)程退出。當(dāng)然, 進(jìn)程可以定義其自身的信號(hào)處理過程。 一旦信號(hào)產(chǎn)生, 這個(gè)過程就將被調(diào)用。 它 的地址存儲(chǔ)在 sigaction 結(jié)構(gòu)中。核心必須調(diào)用進(jìn)程的信號(hào)處理例程, 具體如何 去做依賴于處理器類型,但是所有的CPU必須處

8、理這個(gè)問題:如果信號(hào)產(chǎn)生時(shí), 當(dāng)前進(jìn)程正在核心模式下運(yùn)行并且馬上要返回調(diào)用核心或者系統(tǒng)例程的進(jìn)程, 而 該進(jìn)程處在用戶模式下。 解決這個(gè)問題需要操縱進(jìn)程的堆棧及寄存器。 進(jìn)程的程 序計(jì)數(shù)器被設(shè)置成其信號(hào)處理過程的地址, 而參數(shù)通過調(diào)用框架或者寄存器傳遞 到處理例程中。當(dāng)進(jìn)程繼續(xù)執(zhí)行時(shí),信號(hào)處理例程好象普通的函數(shù)調(diào)用一樣。Linux是POSIX兼容的,所以當(dāng)某個(gè)特定信號(hào)處理例程被調(diào)用時(shí),進(jìn)程可以設(shè)定 哪個(gè)信號(hào)可以阻塞。這意味著可以在進(jìn)程信號(hào)處理過程中改變 blocked 屏蔽碼。 當(dāng)信號(hào)處理例程結(jié)束時(shí),此 blocked 屏蔽碼必須設(shè)置成原有值。 因此, Linux 添加了一個(gè)過程調(diào)用來進(jìn)行整理

9、工作, 通過它來重新設(shè)置被發(fā)送信號(hào)進(jìn)程調(diào)用棧中的原有blocked屏蔽碼。對(duì)于同一時(shí)刻幾個(gè)信號(hào)處理過程,Linux通過堆棧 方式來優(yōu)化其使用,每當(dāng)一個(gè)處理過程退出時(shí),下一個(gè)處理過程必須等到整理例 程結(jié)束后才執(zhí)行。管道般的Linux shell 程序都允許重定向。如$ Is | pr | lpr在這個(gè)管道應(yīng)用中,ls列當(dāng)前目錄的輸出被作為標(biāo)準(zhǔn)輸入送到 pr程序中,而pr 的輸出又被作為標(biāo)準(zhǔn)輸入送到lpr程序中。管道是單向的字節(jié)流,它將某個(gè)進(jìn)程 的標(biāo)準(zhǔn)輸出連接到另外進(jìn)程的標(biāo)準(zhǔn)輸入。但是使用管道的進(jìn)程都不會(huì)意識(shí)到重定 向的存在,并且其執(zhí)行結(jié)果也不會(huì)有什么不同。shell程序負(fù)責(zé)在進(jìn)程間建立臨時(shí)的管道

10、。Prxm 2filefileP IpeWe iteOperationsPipeRe sriOpersti cm百i管道在 Linux 中,管道是通過指向同一個(gè)臨時(shí) VFS inode 的兩個(gè) file 數(shù)據(jù)結(jié)構(gòu)來實(shí) 現(xiàn)的,此VFS in ode指向內(nèi)存中的一個(gè)物理頁面。圖 5.1中每個(gè)file 數(shù)據(jù)結(jié)構(gòu) 指向不同的文件操作例程向量,一個(gè)是實(shí)現(xiàn)對(duì)管道的寫,另一個(gè)從管道中讀。這樣就隱藏了讀寫管道和讀寫普通的文件時(shí)系統(tǒng)調(diào)用的差別。 當(dāng)寫入進(jìn)程對(duì)管道 寫時(shí),字節(jié)被拷貝到共享數(shù)據(jù)頁面中, 當(dāng)讀取進(jìn)程從管道中讀時(shí), 字節(jié)從共享數(shù) 據(jù)頁面中拷貝出來。 Linux 必須同步對(duì)管道的訪問。它必須保證讀者和寫者

11、以確 定的步驟執(zhí)行,為此需要使用鎖、等待隊(duì)列和信號(hào)等同步機(jī)制。當(dāng)寫者想對(duì)管道寫入時(shí), 它使用標(biāo)準(zhǔn)的寫庫(kù)函數(shù)。 表示打開文件和打開管道的描 敘符用來對(duì)進(jìn)程的 file 數(shù)據(jù) 結(jié)構(gòu)集合進(jìn)行索引。 Linux 系統(tǒng)調(diào)用使用由管道 file 數(shù)據(jù)結(jié)構(gòu)指向的 write 過程。這個(gè) write 過程用保存在表示管道的 VFSinode 中的信息來管理寫請(qǐng)求。如果沒有足夠的空間容納對(duì)所有寫入管道的數(shù)據(jù), 只要管道沒有被讀者加鎖。 則 Linux 為寫者加鎖, 并把從寫入進(jìn)程地址空間中寫入的字節(jié)拷貝到共享數(shù)據(jù)頁面 中去。如果管道被讀者加鎖或者沒有足夠空間存儲(chǔ)數(shù)據(jù),當(dāng)前進(jìn)程將在管道 inode 的等待隊(duì)列中睡

12、眠,同時(shí)調(diào)度管理器開始執(zhí)行以選擇其它進(jìn)程來執(zhí)行。如 果寫入進(jìn)程是可中斷的, 則當(dāng)有足夠的空間或者管道被解鎖時(shí), 它將被讀者喚醒。 當(dāng)數(shù)據(jù)被寫入時(shí),管道的 VFSinode 被解鎖,同時(shí)任何在此 inode 的等待隊(duì)列上 睡眠的讀者進(jìn)程都將被喚醒。從管道中讀出數(shù)據(jù)的過程和寫入類似。進(jìn)程允許進(jìn)行非阻塞讀 (這依賴于它們打開文件或者管道的方式) ,此時(shí)如果沒 有數(shù)據(jù)可讀或者管道被加鎖, 則返回錯(cuò)誤信息表明進(jìn)程可以繼續(xù)執(zhí)行。阻塞方 式則使讀者進(jìn)程在管道 inode 的等待隊(duì)列上睡眠直到寫者 進(jìn)程結(jié)束。當(dāng)兩個(gè)進(jìn) 程對(duì)管道的使用結(jié)束時(shí),管道 inode 和共享數(shù)據(jù)頁面將同時(shí)被遺棄。Linux還支持命名管道

13、(named pipe),也就是FIFO管道,因?yàn)樗偸前凑障冗M(jìn) 先出的原則工作。第一個(gè)被寫入 的數(shù)據(jù)將首先從管道中讀出來。和其它管道不 一樣,F(xiàn)IFO管道不是臨時(shí)對(duì)象,它們是文件系統(tǒng)中的實(shí)體并且 可以通過mkfifo 命令來創(chuàng)建。進(jìn)程只要擁有適當(dāng)?shù)臋?quán)限就可以自由使用 FIFO管道。打開FIFO 管道的方式稍有不同。 其它管道需要先創(chuàng)建(它的兩個(gè) file 數(shù)據(jù)結(jié)構(gòu), VFSinode 和共享數(shù)據(jù)頁面)而FIFO管道已經(jīng)存在,只需要由使用者打開與關(guān)閉。在寫者 進(jìn)程打開它之前,Linux必須讓讀者進(jìn)程先打開此 FIFO管道;任何讀者進(jìn)程從 中讀取之前必須有寫者進(jìn)程向其寫入數(shù)據(jù)。FIFO管道的使用

14、方法與普通管道基 本相同,同時(shí)它們使用相同數(shù)據(jù)結(jié)構(gòu)和操作。套接口系統(tǒng) V IPC 機(jī)制Linux支持Unix系統(tǒng)V( 1983)版本中的三種進(jìn)程間通訊機(jī)制。它們是消息隊(duì)列、 信號(hào)燈以及共享內(nèi)存。這些系統(tǒng) VIPC機(jī)制使用共同的授權(quán)方法。只有通過系統(tǒng) 調(diào)用將標(biāo)志符傳遞給核心之后,進(jìn)程才能存取這些資源。這些系統(tǒng)VIPC對(duì)象使用與文件系統(tǒng)非常類似的訪問控制方式。對(duì)象的引用標(biāo)志符被用來作為資源表中 的索引。這個(gè)索引值需要一些處理后才能得到。系統(tǒng)中所有系統(tǒng)V IPC對(duì)象的Linux數(shù)據(jù)結(jié)構(gòu)包含一個(gè)ipc_perm結(jié)構(gòu),它含有 進(jìn)程擁有者和創(chuàng)建者及組標(biāo)志符。另外還有對(duì)此對(duì)象(擁有者,組及其它)的存 取模式

15、以及IPC對(duì)象鍵。此鍵值被用來定位系統(tǒng) VIPC對(duì)象的引用標(biāo)志符。這樣 的鍵值一共有兩組:公有與私有。如果此鍵為公有,則系統(tǒng)中任何接受權(quán)限檢查 的進(jìn)程都可以找到系統(tǒng) VIPC對(duì)象的引用標(biāo)志符。系統(tǒng) VIPC對(duì)象絕不能用一個(gè) 鍵值來引用,而只能使用引用標(biāo)志符。消息隊(duì)列消息隊(duì)列允許一個(gè)或者多個(gè)進(jìn)程向它寫入與讀取消息。Linux維護(hù)著一個(gè)msgque 消息隊(duì)列鏈表,其中每個(gè)元素指向一個(gè)描敘消息隊(duì)列的msqid_ds結(jié)構(gòu)。當(dāng)創(chuàng)建 新的消息隊(duì)列時(shí),系統(tǒng)將從系統(tǒng)內(nèi)存中分配一個(gè)msqid_ds結(jié)構(gòu),同時(shí)將其插入到數(shù)組中。JTTEg um系統(tǒng)V IPC消息隊(duì)列每個(gè)msqid_ds結(jié)構(gòu)包含一個(gè)ipc_perm結(jié)

16、構(gòu)和指向已經(jīng)進(jìn)入此隊(duì)列消息的指針 另外,Linux保留有關(guān)隊(duì)列修改時(shí)間信息,如上次系統(tǒng)向隊(duì)列中寫入的時(shí)間等。 msqid_ds包含兩個(gè)等待隊(duì)列:一個(gè)為隊(duì)列寫入進(jìn)程使用而另一個(gè)由隊(duì)列讀取進(jìn) 程使用。每次進(jìn)程試圖向?qū)懭腙?duì)列寫入消息時(shí), 系統(tǒng)將把其有效用戶和組標(biāo)志符與此隊(duì)列 的 ipc_perm 結(jié)構(gòu)中的模式進(jìn)行比較。如果允許寫入操作,則把此消息從此進(jìn)程 的地址空間拷貝到msg數(shù)據(jù)結(jié)構(gòu)中,并放置到此消息隊(duì)列尾部。由于 Linux嚴(yán) 格限制可寫入消息的個(gè)數(shù)和長(zhǎng)度, 隊(duì)列中可能容納不下這個(gè)消息。 此時(shí), 此寫入 進(jìn)程將被添加到這個(gè)消息隊(duì)列的等待隊(duì)列中, 同時(shí)調(diào)用調(diào)度管理器選擇新進(jìn)程運(yùn) 行。當(dāng)由消息從此隊(duì)

17、列中釋放時(shí),該進(jìn)程將被喚醒。從隊(duì)列中讀的過程與之類似。 進(jìn)程對(duì)這個(gè)寫入隊(duì)列的訪問權(quán)限將被再次檢驗(yàn)。 讀 取進(jìn)程將選擇隊(duì)列中第一個(gè)消息 (不管是什么類型) 或者第一個(gè)某特定類型的消 息。如果沒有消息可以滿足此要求,讀取進(jìn)程將被添加 到消息隊(duì)列的讀取等待 隊(duì)列中,然后系統(tǒng)運(yùn)行調(diào)度管理器。 當(dāng)有新消息寫入隊(duì)列時(shí), 進(jìn)程將被喚醒繼續(xù) 執(zhí)行。信號(hào)燈信號(hào)燈最簡(jiǎn)單的形式是某個(gè)可以被多個(gè)進(jìn)程檢驗(yàn)和設(shè)置 (test&set) 的內(nèi)存單元。 這個(gè)檢驗(yàn)與設(shè)置操作對(duì)每個(gè)進(jìn)程而言是不可中斷或者說是一個(gè)原子性操作; 一旦 啟動(dòng)誰也終止不了。檢驗(yàn)與設(shè)置操作的結(jié)果是信號(hào)燈當(dāng)前值加 1, 這個(gè)值可以 是正數(shù)也可以是負(fù)數(shù)

18、。 根據(jù)這個(gè)操作的結(jié)果, 進(jìn)程可能可以一直睡眠到此信號(hào)燈 的值被另一個(gè)進(jìn)程更改為止。信號(hào)燈可用來實(shí)現(xiàn)臨界區(qū) (critical region) :某 一時(shí)刻在此區(qū)域內(nèi)的代碼只能被一個(gè)進(jìn)程執(zhí)行。如果你有多個(gè)協(xié)作進(jìn)程從一個(gè)數(shù)據(jù)文件中讀取與寫入記錄。 有時(shí)你可能需要這些 文件訪問遵循嚴(yán)格的訪問次序。 那么可在文件操作代碼上使用一個(gè)初始值為 1 的信號(hào)燈,它帶有兩個(gè)信號(hào)燈操作,一個(gè)檢驗(yàn)并對(duì)信號(hào)燈 值減 1,而另一個(gè)檢 驗(yàn)并加 1。第一個(gè)訪問文件的進(jìn)程將試圖將信號(hào)燈值減 1,如果獲得成功則信號(hào) 燈值變成了 0 。此進(jìn)程于是開始使用這個(gè)數(shù)據(jù)文件, 但是此時(shí)如果另一進(jìn)程也想 將信號(hào)燈值減 1,則信號(hào)燈值將為

19、 -1 ,這次操作將會(huì)失敗。它將掛起執(zhí)行直到第 一個(gè)進(jìn)程完成對(duì)此數(shù)據(jù)文件的使用。 此時(shí)這個(gè)等待進(jìn)程將被喚醒, 這次它對(duì)信號(hào) 燈的操作將成功。系統(tǒng)V IPC信號(hào)燈每個(gè)系統(tǒng)V IPC信號(hào)燈對(duì)象對(duì)應(yīng)一個(gè)信號(hào)燈數(shù)組,Linux使用semid_ds結(jié)構(gòu)來 表示。系統(tǒng)中所有semid_ds結(jié)構(gòu)由一組semary指針來指示。在每個(gè)信號(hào)燈數(shù)組 中有一個(gè)sem_nsem§它表示一個(gè)由sem_base指向的sem結(jié)構(gòu)。授權(quán)的進(jìn)程可 以使用系統(tǒng)調(diào)用來操縱這些包含系統(tǒng) V ipC信號(hào)燈對(duì)象的信號(hào)燈數(shù)組。這個(gè)系統(tǒng) 調(diào)用可以定義許多種操作,每個(gè)操作用三個(gè)輸入來描敘:信號(hào)燈索引、操作值和 一組標(biāo)志。信號(hào)燈索引是一

20、個(gè)信號(hào)燈數(shù)組的索引,而操作值是將被加到信號(hào)燈上 的數(shù)值。首先Linux將檢查是否所有操作已經(jīng)成功。如果操作值與信號(hào)燈當(dāng)前數(shù) 值相加大于0,或者操作值與信號(hào)燈當(dāng)前值都是 0,操作將會(huì)成功。如果所有信 號(hào)燈操作失敗,Linux僅僅會(huì)把那些操作標(biāo)志沒有要求系統(tǒng)調(diào)用為非阻塞類型的 進(jìn)程掛起。進(jìn)程掛起后,Linux必須保存信號(hào)燈操作的執(zhí)行狀態(tài)并將當(dāng)前進(jìn)程放 入等待隊(duì)列。系統(tǒng)還在堆棧上建立sem_queue結(jié)構(gòu)并填充各個(gè)域。這個(gè)sem_queue 結(jié)構(gòu)將被放到此信號(hào)燈對(duì)象等待隊(duì)列的尾部(使用sem_pending和sem_pendingast指針)。系統(tǒng)把當(dāng)前進(jìn)程置入 sem_queue結(jié)構(gòu)中的等待隊(duì)列(

21、sleeper)中,然后啟動(dòng)調(diào)度管理器選擇其它進(jìn)程運(yùn)行。一如果所有這些信號(hào)燈操作都成功則無需掛起當(dāng)前進(jìn)程,Linux將對(duì)信號(hào)燈數(shù)組中的其他成員進(jìn)行相同操作,然后檢查那些處于等待或者掛起狀態(tài)的進(jìn)程。首先, Linux將依次檢查掛起隊(duì)列(sem_pending)中的每個(gè)成員,看信號(hào)燈操作能否繼 續(xù)。如果可以則將其sem_queue結(jié)構(gòu)從掛起鏈表中刪除并對(duì)信號(hào)燈數(shù)組發(fā)出信號(hào) 燈操作。Linux還將喚醒處于睡眠狀態(tài)的進(jìn)程并使之成為下一個(gè)運(yùn)行的進(jìn)程。如 果在對(duì)掛起隊(duì)列的遍歷過程中有的信號(hào)燈操作不能完成則Linux將一直重復(fù)此過程,直到所有信號(hào)燈操作完成且沒有進(jìn)程需要繼續(xù)睡眠。但是信號(hào)燈的使用可能產(chǎn)生一個(gè)

22、嚴(yán)重的問題: 死鎖。當(dāng)一個(gè)進(jìn)程進(jìn)入臨界區(qū)時(shí)它 改變了信號(hào)燈的值而離開臨界區(qū)時(shí)由于運(yùn)行失敗或者被 kill 而沒有改回信號(hào)燈 時(shí),死鎖將會(huì)發(fā)生。 Linux 通過維護(hù)一組描敘信號(hào)燈數(shù)組變化的鏈表來防止該現(xiàn) 象的發(fā)生。它的具體做法是讓 Linux 將把此信號(hào)燈設(shè)置為進(jìn)程對(duì)其進(jìn)行操作前的 狀態(tài)。這些狀態(tài)值被保存在使用該信號(hào)燈數(shù)組進(jìn)程的 semid_ds 和 task_struct 結(jié)構(gòu)的sem_undo結(jié)構(gòu)中。信號(hào)燈操作將迫使系統(tǒng)對(duì)它引起的狀態(tài)變化進(jìn)行維護(hù)。 Linux 為每個(gè)進(jìn)程維護(hù)至 少一個(gè)對(duì)應(yīng)于信號(hào)燈數(shù)組的sem_u ndo結(jié)構(gòu)。如果請(qǐng)求進(jìn)行信號(hào)燈操作的進(jìn)程沒 有該結(jié)構(gòu),則必要時(shí) Linux

23、會(huì)為其創(chuàng)建一個(gè)。這個(gè) sem_undo 結(jié)構(gòu)將同時(shí)放入此 進(jìn)程的 task_struct 結(jié)構(gòu)和此信號(hào)燈數(shù)組的 semid_ds 結(jié)構(gòu)中。當(dāng)對(duì)信號(hào)燈進(jìn)行 操作時(shí),信號(hào)燈變化值的負(fù)數(shù)被置入進(jìn)程的sem_u ndo纟吉構(gòu)中該信號(hào)的入口中。所以當(dāng)操作值為 2 時(shí),則此信號(hào)燈的調(diào)整入口中將加入一個(gè) -2。象正常退出一樣,當(dāng)進(jìn)程被刪除時(shí),Linux將遍歷該進(jìn)程的sem_undo集合對(duì)信 號(hào)燈數(shù)組使用調(diào)整值。如果信號(hào)燈集合被刪除而 sem_u ndo數(shù)據(jù)結(jié)構(gòu)還在進(jìn)程的 task_struct 結(jié)構(gòu)中則此信號(hào)燈數(shù)組標(biāo)志符將被置為無效。此時(shí) 信號(hào)燈清除代 碼只需丟棄sem_undo結(jié)構(gòu)即可。共享內(nèi)存共享內(nèi)存允

24、許一個(gè)或多個(gè)進(jìn)程通過同時(shí)出現(xiàn)在它們虛擬地址空間中的內(nèi)存來通 訊。此虛擬內(nèi)存的頁面出現(xiàn)在每個(gè)共享進(jìn)程頁表中。 但此頁面并不一定位于所有 共享進(jìn)程虛擬內(nèi)存的相同位置。和其它系統(tǒng)V IPC 對(duì)象的使用方法一樣,對(duì)共享內(nèi)存區(qū)域的訪問是通過鍵和訪問權(quán)限檢驗(yàn)來控制的。 一旦內(nèi)存被共享, 則再不會(huì) 檢驗(yàn)進(jìn)程對(duì)對(duì)象的使用方式。它依賴于其它機(jī)制,如系統(tǒng)V信號(hào)燈,來同步對(duì)共 享內(nèi)存的訪問。shmid de系統(tǒng)V IPC共享內(nèi)存每個(gè)新創(chuàng)建的共享內(nèi)存區(qū)域由一個(gè) shmid_ds數(shù)據(jù)結(jié)構(gòu)來表示。它們被保存再 shm_segs數(shù)組中。shmid_ds數(shù)據(jù)結(jié)構(gòu)描敘共享內(nèi)存的大小,進(jìn)程如何使用以及 共享內(nèi)存映射到其各自地址空間的方式。由共享內(nèi)存創(chuàng)建者控制對(duì)此內(nèi)存的存取 權(quán)限以及其鍵是公有還是私有。如果它由足夠權(quán)限,它還可以將此共享內(nèi)存加載 到物理內(nèi)存中。每個(gè)使

溫馨提示

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

最新文檔

評(píng)論

0/150

提交評(píng)論