進(jìn)程間的通信(IPC)如何實(shí)現(xiàn)?
1、管道( pipe )
既可在程序中使用,也可在shell中使用。
管道是一種半雙工的通信方式,數(shù)據(jù)只能單向流動。
管道的問題在于他們沒有名字,只能在具有親緣關(guān)系(父子進(jìn)程間)的進(jìn)程間使用。
擴(kuò)展:
管道由pipe函數(shù)創(chuàng)建,提供一個單向數(shù)據(jù)流。當(dāng)需要一個雙向數(shù)據(jù)流時,我們必須創(chuàng)建兩個管道,每個方向一個。這也就是全雙工管道的實(shí)現(xiàn)原理:由兩個半雙工管道構(gòu)成。
2、命名管道 (named pipe) :即FIFO
命名管道也是半雙工的通信方式。提供單向數(shù)據(jù)流。
克服了管道沒有名字的限制,因此允許無親緣關(guān)系的進(jìn)程間通信,解決了管道的上述問題。
擴(kuò)展:
管道和FIFO都是使用通常的read和write函數(shù)訪問。
FIFO由mkfifo函數(shù)創(chuàng)建。FIFO不同于管道的是,每個FIFO有一個路徑名與之關(guān)聯(lián),從而允許無親緣關(guān)系的進(jìn)程訪問同一FIFO。
FIFO的真正優(yōu)勢表現(xiàn)在服務(wù)器可以是一個長期運(yùn)行的進(jìn)程(如守護(hù)進(jìn)程),而且與其客戶可以無親緣關(guān)系。
3、信號量( semophore )
主要作為進(jìn)程間以及同一進(jìn)程內(nèi)不同線程之間的同步手段。
進(jìn)程間通信處理同步互斥的機(jī)制。信號量是一個計數(shù)器,可以用來控制多個進(jìn)程對共享資源的訪問。它常作為一種鎖機(jī)制,防止某進(jìn)程正在訪問共享資源時,其他進(jìn)程也訪問該資源。
4、信號 ( sinal )
是一種處理異步事件的方式。
信號是一種比較復(fù)雜的通信方式,用于通知接收進(jìn)程某個事件已經(jīng)發(fā)生。除了用于進(jìn)程外,還可以發(fā)送信號給進(jìn)程本身。
信號和信號量是不同的,他們雖然都可用來實(shí)現(xiàn)同步和互斥,但前者是使用信號處理器來進(jìn)行的,后者是使用P,V操作來實(shí)現(xiàn)的。
5、消息隊(duì)列( message queue )
消息隊(duì)列是消息的鏈表,包括Posix消息隊(duì)列systemV消息隊(duì)列。
有足夠權(quán)限的進(jìn)程都可以向隊(duì)列中添加消息,有足夠讀權(quán)限的進(jìn)程都可以讀走隊(duì)列中的消息。
消息隊(duì)列克服了信號承載信息量少,管道只能承載無格式字節(jié)流以及緩沖區(qū)大小受限等缺點(diǎn)。
擴(kuò)展:
消息隊(duì)列具有隨內(nèi)核的持續(xù)性,這跟管道和FIFO不一樣。當(dāng)一個管道或FIFO的最后一次關(guān)閉發(fā)生時,仍在該管道或FIFO上的數(shù)據(jù)將被丟棄。
兩種消息隊(duì)列:都不使用真正的描述符,因此在消息隊(duì)列上使用select或poll是困難的。兩種消息隊(duì)列:在某個進(jìn)程往一個隊(duì)列寫入消息之前,并不需要另外某個進(jìn)程在該隊(duì)列上等待消息的到達(dá)。
SystemV消息隊(duì)列的問題之一是無法通知一個進(jìn)程何時在某個隊(duì)列中放置了一個消息,也就是無法窺探一個消息。而Posix消息隊(duì)列允許異步事件通知,以告知何時有一個消息放置到了某個空消息隊(duì)列中。
Posix消息隊(duì)列缺失的主要特性是從隊(duì)列中讀出指定優(yōu)先級消息的能力。
使用管道和FIFO時,為在兩個方向上交換數(shù)據(jù),需要兩個IPC通道。而使用消息隊(duì)列時單個隊(duì)列就夠用,由每個消息的類型來標(biāo)識該消息是從客戶到服務(wù)器還是從服務(wù)器到客戶。
Posix消息隊(duì)列消息鏈表的鏈表頭中含有當(dāng)前隊(duì)列的兩個屬性:隊(duì)列中允許的最大消息數(shù)和每個消息的最大大小。
Posix消息隊(duì)列消息隊(duì)列的2個限制:一個進(jìn)程能同時擁有打開著的消息隊(duì)列的最大數(shù)目;任意消息的最大優(yōu)先級。
6、共享內(nèi)存( shared memory )
是由一個進(jìn)程創(chuàng)建,但多個進(jìn)程都可以訪問的同一塊內(nèi)存空間。是最快的可用IPC形式(因?yàn)楣蚕韮?nèi)存區(qū)中的單個數(shù)據(jù)副本對于共享該內(nèi)存的所有線程或進(jìn)程都是可用的)。
是針對其他通信機(jī)制運(yùn)行效率較低而設(shè)計的。往往與其它通信機(jī)制,如信號量結(jié)合使用,來達(dá)到進(jìn)程間的同步和通信。
一般IPC形式(管道、FIFO、消息隊(duì)列)的問題在于,兩個進(jìn)程要交換信息,這些信息必須經(jīng)由內(nèi)核傳遞。而進(jìn)程間共享內(nèi)存時,交換數(shù)據(jù)就不再涉及內(nèi)核。這些進(jìn)程必須協(xié)調(diào)或同步對該共享內(nèi)存區(qū)的使用。
將共享內(nèi)存區(qū)用于客戶-服務(wù)器文件復(fù)制:該共享內(nèi)存區(qū)同時存在于客戶和服務(wù)器的地址空間。
數(shù)據(jù)只需復(fù)制兩次:一次從輸入文件到共享內(nèi)存區(qū),另一次從共享內(nèi)存區(qū)到輸出文件。
然而其他IPC形式(管道、FIFO、消息隊(duì)列)則需要四次復(fù)制:
另外,默認(rèn)情況下通過fork派生的子進(jìn)程并不與其父進(jìn)程共享內(nèi)存區(qū)。?。?!
7、套接字( socket )
更為一般的進(jìn)程間通信機(jī)制,可用于不同機(jī)器之間的進(jìn)程間通信。
8、遠(yuǎn)程過程調(diào)用:RPC
構(gòu)筑一個應(yīng)用程序時,如果所有進(jìn)程都在同一臺主機(jī),那么可以使用前面的各種IPC方式;如果進(jìn)程不在同一個主機(jī)上,那就要求進(jìn)程間使用某種形式的網(wǎng)絡(luò)通信,RPC提供了這樣一種工具,它屬于隱式網(wǎng)絡(luò)編程的范疇。
RPC是用于從一個系統(tǒng)(客戶主機(jī))上某個程序調(diào)用另一個系統(tǒng)上(服務(wù)器主機(jī))某個函數(shù)的一種方法。
它的調(diào)用進(jìn)程和被調(diào)用進(jìn)程可在不同主機(jī)上執(zhí)行,客戶和服務(wù)器運(yùn)行在不同主機(jī)上,而且過程調(diào)用中涉及網(wǎng)絡(luò)I/O,對于程序員是透明的。
另外,RPC也可用于同一主機(jī)上的客戶和服務(wù)器之間,因此也可認(rèn)為是另一種形式的消息傳遞。
補(bǔ)充:
作業(yè):用戶在一次解題或一個事務(wù)處理過程中要求計算機(jī)系統(tǒng)所做工作的集合。它包括用戶程序、所需要的數(shù)據(jù)及控制命令等。作業(yè)是由一系列有序的步驟組成的。
進(jìn)程:一個程序在一個數(shù)據(jù)集上的一次運(yùn)行過程。所以一個程序在不同數(shù)據(jù)集合上運(yùn)行,乃至一個程序在同樣數(shù)據(jù)集合上多次運(yùn)行都是不同的進(jìn)程。
線程:線程是進(jìn)程中的一個實(shí)體,是被系統(tǒng)獨(dú)立調(diào)度和執(zhí)行的基本單位。
管程:管程實(shí)際上是定義了一個數(shù)據(jù)結(jié)構(gòu)和在該數(shù)據(jù)結(jié)構(gòu)上的能為并發(fā)進(jìn)程所執(zhí)行的一組操作,這組操作能同步進(jìn)程和改變管程中的數(shù)據(jù)。管程的基本思想是,將共享變量和對它們的操作集中在一個模塊中,操作系統(tǒng)或并發(fā)程序就由這樣的模塊構(gòu)成。這樣模塊之間聯(lián)系清晰,便于維護(hù)和修改,易于保證正確性。管程有一個很重要的特性,即任一時刻管程中只能有一個活躍進(jìn)程,這一特性使管程能有效地完成互斥。用管程實(shí)現(xiàn)進(jìn)程同步時,管程中的過程是不可中斷的。
評論
查看更多