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