APUE读书笔记-第15章-进程间通信
15.1 引言
*進(jìn)程之間交換信息的方法可以經(jīng)由fork或exec傳送打開文件,或者通過文件系統(tǒng)
*進(jìn)程之間相互通信的其他技術(shù)——IPC(InterProcess Communication)包括半雙工管道、FIFO、全雙工管道、命名全雙工管道、消息隊(duì)列、信號量、共享存儲、套接字、STREAMS
15.2 管道
*管道有兩種局限性:(1)歷史上,它們是半雙工的(即數(shù)據(jù)只能在一個(gè)方向上流動)(2)它們只能在具有公共祖先的進(jìn)程之間使用
*每當(dāng)你在管道線中鍵入一個(gè)由shell執(zhí)行的命名序列時(shí),shell為每一條命令單獨(dú)創(chuàng)建一進(jìn)程,然后將前一條命令進(jìn)程的標(biāo)準(zhǔn)輸出用管道與后一條命令的標(biāo)準(zhǔn)輸入相連接
*管道是由調(diào)用pipe函數(shù)而創(chuàng)建的
15.3 popen和pclose函數(shù)
*常見的操作是創(chuàng)建一個(gè)管道連接到另一個(gè)進(jìn)程,然后讀其輸出或向其輸入端發(fā)送數(shù)據(jù)。為此,標(biāo)準(zhǔn)I/O庫提供了兩個(gè)函數(shù)popen和pclose。這兩個(gè)函數(shù)實(shí)現(xiàn)的操作是:創(chuàng)建一個(gè)管道,調(diào)用fork產(chǎn)生一個(gè)進(jìn)程,關(guān)閉管道的不使用端,執(zhí)行一個(gè)shell以運(yùn)行命令,然后等待命令終止
15.4 協(xié)同進(jìn)程
*UNIX系統(tǒng)過濾程序從標(biāo)準(zhǔn)輸入讀取數(shù)據(jù),對其進(jìn)行適當(dāng)處理后寫到標(biāo)準(zhǔn)輸出。幾個(gè)過濾程序通常在shell管道命令行中線性的連接。當(dāng)一個(gè)程序產(chǎn)生某個(gè)過濾程序的輸入,同時(shí)又讀取該過濾程序的輸出時(shí),則該過濾程序就稱為協(xié)同進(jìn)程(coprocess)
*標(biāo)準(zhǔn)I/O的緩沖機(jī)制問題的解決方法是使被調(diào)用的協(xié)同進(jìn)程(在本例中是awk)認(rèn)為它的標(biāo)準(zhǔn)輸入和輸出都被連接到一個(gè)終端
15.5 FIFO
*FIFO有時(shí)被稱為命名管道。管道只能由相關(guān)進(jìn)程使用,這些相關(guān)進(jìn)程的共同的祖先進(jìn)程創(chuàng)建了管道。(一個(gè)例外是已裝配的基于STREAMS的管道)。但是,通過FIFO,不相關(guān)的進(jìn)程也能交換數(shù)據(jù)。
*FIFO有下面兩種用途:
(1)FIFO由shell命令使用以便將數(shù)據(jù)從一條管道線傳送到另一條,為此無需創(chuàng)建中間臨時(shí)文件
(2)FIFO用于客戶進(jìn)程-服務(wù)器進(jìn)程應(yīng)用程序中,以在客戶進(jìn)程和服務(wù)器進(jìn)程之間傳遞數(shù)據(jù)
15.6 XSI IPC
*有三種IPC我們稱作XSI IPC,即消息隊(duì)列、信號量以及共享存儲器,它們之間有很多相似之處
*每個(gè)內(nèi)核中的IPC結(jié)構(gòu)(消息隊(duì)列、信號量或共享存儲段)都用一個(gè)非負(fù)整數(shù)的標(biāo)識符(identifier)加以引用
*標(biāo)識符是IPC對象的內(nèi)部名。為使多個(gè)合作進(jìn)程能夠在同一IPC對象上會合,需要提供一個(gè)外部名方案。為此使用鍵(key),每個(gè)IPC對象都與一個(gè)鍵相關(guān)聯(lián),于是鍵就用作為該對象的外部名
*有多種方法可以使客戶進(jìn)程和服務(wù)器進(jìn)程在同一IPC結(jié)構(gòu)上會合:
(1)服務(wù)器進(jìn)程可以指定鍵IPC_PRIVATE創(chuàng)建一個(gè)新IPC結(jié)構(gòu),將返回的標(biāo)識符存放在某處(例如一個(gè)文件)以便客戶進(jìn)程取用。鍵IPC_PRIVATE保證服務(wù)器進(jìn)程創(chuàng)建一個(gè)新IPC結(jié)構(gòu)。IPC_PRIVATE鍵也可用于父子進(jìn)程關(guān)系。父進(jìn)程指定IPC_PRIVATE創(chuàng)建一個(gè)新IPC結(jié)構(gòu),所返回的標(biāo)識符在調(diào)用fork之后可由子進(jìn)程使用。接著,子進(jìn)程又可將此標(biāo)識符作為exec函數(shù)的一個(gè)參數(shù)傳給一個(gè)新程序
(2)在一個(gè)公用頭文件中定義一個(gè)客戶進(jìn)程和服務(wù)器進(jìn)程都認(rèn)可的鍵。然后服務(wù)器進(jìn)程指定此鍵創(chuàng)建一個(gè)新的IPC結(jié)構(gòu)
(3)客戶進(jìn)程和服務(wù)器進(jìn)程認(rèn)同一個(gè)路徑名和項(xiàng)目ID(項(xiàng)目ID是0~255之間的字符值),接著調(diào)用函數(shù)ftok將這兩個(gè)值變換為一個(gè)鍵。然后在方法(2)中使用此鍵。ftok提供的唯一服務(wù)就是由一個(gè)路徑名和項(xiàng)目ID產(chǎn)生一個(gè)鍵
15.7 消息隊(duì)列
*msgget創(chuàng)建一個(gè)新隊(duì)列或打開一個(gè)現(xiàn)存的隊(duì)列。msgsnd將新消息添加到隊(duì)列尾端。每個(gè)消息包含一個(gè)正長整數(shù)類型字段,一個(gè)非負(fù)長度以及實(shí)際數(shù)據(jù)字節(jié)(對應(yīng)于長度),所有這些都在講消息添加到隊(duì)列時(shí),傳送給msgsnd。msgrcv用于從隊(duì)列中取消息。
*每個(gè)消息由三部分組成,它們是:正長整型類型字段、非負(fù)長度(nbytes)以及實(shí)際數(shù)據(jù)字節(jié)(對應(yīng)于長度)。消息總是放在隊(duì)列尾端
*若消息隊(duì)列已滿(或者是隊(duì)列中的消息總數(shù)等于系統(tǒng)限制值,或隊(duì)列中的字節(jié)總數(shù)等于系統(tǒng)限制值),則指定IPC_NOWAIT使得msgsnd立即出錯(cuò)返回EAGAIN。如果沒有指定IPC_NOWAIT,則進(jìn)程阻塞直到下述情況出現(xiàn)為止:有空間可以容納要發(fā)送的消息;從系統(tǒng)中刪除了此隊(duì)列,或捕捉到一個(gè)信號,并從信號處理程序返回。
15.8 信號量
*信號量(semaphore)與已經(jīng)介紹過的IPC機(jī)構(gòu)(管道、FIFO以及消息隊(duì)列)不同。它是一個(gè)計(jì)數(shù)器,用于多進(jìn)程對共享數(shù)據(jù)對象的訪問
15.9 共享存儲
*共享存儲允許兩個(gè)或更多進(jìn)程共享一給定的存儲區(qū)。因?yàn)閿?shù)據(jù)不需要在客戶進(jìn)程和服務(wù)器進(jìn)程之間復(fù)制,所以這是最快的一種IPC。使用共享存儲時(shí)要掌握的唯一竅門是多個(gè)進(jìn)程之間對一給定存儲區(qū)的同步訪問,若服務(wù)器進(jìn)程正在將數(shù)據(jù)放入共享存儲區(qū),則它做完這一操作之前,客戶進(jìn)程不應(yīng)當(dāng)去取這些數(shù)據(jù)。通常,信號量被用來實(shí)現(xiàn)對共享存儲訪問的同步。(記錄鎖也可用于這種場合)
*為了獲得一個(gè)共享存儲標(biāo)識符,調(diào)用的第一個(gè)函數(shù)通常是shmget
int shmget(key_t key, size_t size, int flag)
*shmctl函數(shù)對共享存儲段執(zhí)行多種操作
int shmctl(int shmid, int cmd, struct shmid_ds *buf)
*cmd參數(shù)指定下列5種命令中一種,使其在shmid指定的段上執(zhí)行
IPC_STAT
IPC_SET
IPC_RMID 從系統(tǒng)中刪除該共享存儲段
SHM_LOCK 將共享存儲段鎖定在內(nèi)存中
SHM_UNLOCK 解鎖共享存儲段
*一旦創(chuàng)建了一個(gè)共享存儲段,進(jìn)程就可調(diào)用shmat將其連接到它的地址空間中
void *shmat(int shmid, const void *addr, int flag)
共享存儲段連接到調(diào)用進(jìn)程的哪個(gè)地址上與addr參數(shù)以及在flag中是否制定SHM_RND位有關(guān)
(1)如果addr為0,則此段連接到由內(nèi)核選擇的第一個(gè)可用地址上
(2)如果addr非0,并且沒有指定SHM_RND,則此段連接到addr所指定的地址上
(3)如果addr非0,并且指定了SHM_RND,則此段連接到(addr-(addr mod ulus SHMLBA))所表示的地址上。SHM_RND命令的意思是“取整”。SHMLBA的意思是“低邊界地址倍數(shù)”,它總是2的乘方
*shmat的返回值是該段所連接的實(shí)際地址,如果出錯(cuò)則返回-1
*當(dāng)對共享存儲段的操作已經(jīng)結(jié)束時(shí),則調(diào)用shmdt脫接該段
int shmdt(void *addr)
*很多實(shí)現(xiàn)提供了一種類似于/dev/zero的設(shè)施,稱為匿名存儲映射
15.10 客戶進(jìn)程-服務(wù)器進(jìn)程屬性
*客戶進(jìn)程和服務(wù)器進(jìn)程的某些屬性受到它們之間所使用的IPC類型的影響。最簡單的關(guān)系類型是使客戶調(diào)用fork然后調(diào)用exec執(zhí)行所希望的服務(wù)器進(jìn)程。在fork之前先創(chuàng)建兩個(gè)半雙工管道使數(shù)據(jù)可在兩個(gè)方向傳輸
?
轉(zhuǎn)載于:https://www.cnblogs.com/james1207/p/3253641.html
總結(jié)
以上是生活随笔為你收集整理的APUE读书笔记-第15章-进程间通信的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 007.androidUI开发进阶(基础
- 下一篇: 洛谷 P2704 [NOI2001]炮兵