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