日本免费全黄少妇一区二区三区-高清无码一区二区三区四区-欧美中文字幕日韩在线观看-国产福利诱惑在线网站-国产中文字幕一区在线-亚洲欧美精品日韩一区-久久国产精品国产精品国产-国产精久久久久久一区二区三区-欧美亚洲国产精品久久久久

Linux 核心--6.進(jìn)程間通訊機(jī)制

第五章 進(jìn)程間通訊機(jī)制

進(jìn)程在核心的協(xié)調(diào)下進(jìn)行相互間的通訊 。Linux支持大量進(jìn)程間通訊(IPC)機(jī)制 。除了信號和管道外 , Linux 還支持Unix系統(tǒng)V中的IPC機(jī)制 。


5.1信號
信號是Unix系統(tǒng)中的最古老的進(jìn)程間通訊方式 。它們用來向一個(gè)或多個(gè)進(jìn)程發(fā)送異步事件信號 。信號可以從鍵盤中斷中產(chǎn)生 , 另外進(jìn)程對虛擬內(nèi)存的非法存取等系統(tǒng)錯(cuò)誤環(huán)境下也會有信號產(chǎn)生 。信號還被shell程序用來向其子進(jìn)程發(fā)送任務(wù)控制命令 。
系統(tǒng)中有一組被詳細(xì)定義的信號類型 , 這些信號可以由核心或者系統(tǒng)中其它具有適當(dāng)權(quán)限的進(jìn)程產(chǎn)生 。使用kill命令(kill -l)可以列出系統(tǒng)中所有已經(jīng)定義的信號 。在我的系統(tǒng)(Intel系統(tǒng))上運(yùn)行結(jié)果如下:

 1) SIGHUP2) SIGINT3) SIGQUIT4) SIGILL
 5) SIGTRAP6) SIGIOT7) SIGBUS8) SIGFPE
 9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2
13) SIGPIPE 14) SIGALRM 15) SIGTERM 17) SIGCHLD
18) SIGCONT 19) SIGSTOP 20) SIGTSTP 21) SIGTTIN
22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO
30) SIGPWR

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

Linux通過存儲在進(jìn)程task_struct中的信息來實(shí)現(xiàn)信號 。信號個(gè)數(shù)受到處理器字長的限制 。32位字長的處理器最多可以有32個(gè)信號而64位處理器如Alpha AXP可以有最多64個(gè)信號 。當(dāng)前未處理的信號保存在signal域中 , 并帶有保存在blocked中的被阻塞信號的屏蔽碼 。除了SIGSTOP和SIGKILL外 , 所有的信號都能被阻塞 。當(dāng)產(chǎn)生可阻塞信號時(shí) , 此信號可以保持一直處于待處理狀態(tài)直到阻塞釋放 。Linux保存著每個(gè)進(jìn)程處理每個(gè)可能信號的信息 , 它們保存在每個(gè)進(jìn)程task_struct中的sigaction數(shù)組中 。這些信息包括進(jìn)程希望處理的信號所對應(yīng)的過程地址 , 或者指示是忽略信號還是由核心來處理它的標(biāo)記 。通過系統(tǒng)調(diào)用 , 進(jìn)程可以修改缺省的信號處理過程 , 這將改變某個(gè)信號的sigaction以及阻塞屏蔽碼 。

并不是系統(tǒng)中每個(gè)進(jìn)程都可以向所有其它進(jìn)程發(fā)送信號:只有核心和超級用戶具有此權(quán)限 。普通進(jìn)程只能向具有相同uid和gid的進(jìn)程或者在同一進(jìn)程組中的進(jìn)程發(fā)送信號 。信號是通過設(shè)置task_struct結(jié)構(gòu)中signal域里的某一位來產(chǎn)生的 。如果進(jìn)程沒有阻塞信號并且處于可中斷的等待狀態(tài) , 則可以將其狀態(tài)改成Running , 同時(shí)如確認(rèn)進(jìn)程還處在運(yùn)行隊(duì)列中 , 就可以通過信號喚醒它 。這樣系統(tǒng)下次發(fā)生調(diào)度時(shí) , 調(diào)度管理器將選擇它運(yùn)行 。如果進(jìn)程需要缺省的信號處理過程 , 則Linux可以優(yōu)化對此信號的處理 。例如SIGWINCH(X窗口的焦點(diǎn)改變)信號 , 其缺省處理過程是什么也不做 。

信號并非一產(chǎn)生就立刻交給進(jìn)程 , 而是必須等待到進(jìn)程再次運(yùn)行時(shí)才交給進(jìn)程 。每次進(jìn)程從系統(tǒng)調(diào)用中退出前 , 它都會檢查signal和blocked域 , 看是否有可以立刻發(fā)送的非阻塞信號 。這看起來非常不可靠 , 但是系統(tǒng)中每個(gè)進(jìn)程都在不停地進(jìn)行系統(tǒng)調(diào)用 , 如向終端輸出字符 。當(dāng)然進(jìn)程可以選擇去等待信號 , 此時(shí)進(jìn)程將一直處于可中斷狀態(tài)直到信號出現(xiàn) 。對當(dāng)前不可阻塞信號的處理代碼放置在sigaction結(jié)構(gòu)中 。

推薦閱讀