進(jìn)程通信: 每個(gè)進(jìn)程各自有不同的用戶地址空間,任何一個(gè)進(jìn)程的全局變量在另一個(gè)進(jìn)程中都看不到,,所以進(jìn)程之間要交換數(shù)據(jù)必須通過內(nèi)核,在內(nèi)核中開辟一塊緩沖區(qū),進(jìn)程A把數(shù)據(jù)從用戶空間拷到內(nèi)核緩沖區(qū),進(jìn)程B再?gòu)膬?nèi)核緩沖區(qū)把數(shù)據(jù)讀走,內(nèi)核提供的這種機(jī)制稱為進(jìn)程間通信。 1 匿名管道通信匿名管道( pipe ):管道是一種半雙工的通信方式,數(shù)據(jù)只能單向流動(dòng),,而且只能在具有親緣關(guān)系的進(jìn)程間使用。進(jìn)程的親緣關(guān)系通常是指父子進(jìn)程關(guān)系,。
通過匿名管道實(shí)現(xiàn)進(jìn)程間通信的步驟如下:
詳細(xì)可參考文章:進(jìn)程間的通信方式——pipe(管道) 2 高級(jí)管道通信高級(jí)管道(popen):將另一個(gè)程序當(dāng)做一個(gè)新的進(jìn)程在當(dāng)前程序進(jìn)程中啟動(dòng),,則它算是當(dāng)前程序的子進(jìn)程,,這種方式我們成為高級(jí)管道方式。 3 有名管道通信有名管道 (named pipe) : 有名管道也是半雙工的通信方式,,但是它允許無親緣關(guān)系進(jìn)程間的通信,。 4 消息隊(duì)列通信消息隊(duì)列( message queue ) : 消息隊(duì)列是由消息的鏈表,存放在內(nèi)核中并由消息隊(duì)列標(biāo)識(shí)符標(biāo)識(shí),。消息隊(duì)列克服了信號(hào)傳遞信息少,、管道只能承載無格式字節(jié)流以及緩沖區(qū)大小受限等缺點(diǎn)。 5 信號(hào)量通信信號(hào)量( semophore ) : 信號(hào)量是一個(gè)計(jì)數(shù)器,,可以用來控制多個(gè)進(jìn)程對(duì)共享資源的訪問,。它常作為一種鎖機(jī)制,,防止某進(jìn)程正在訪問共享資源時(shí),其他進(jìn)程也訪問該資源,。因此,,主要作為進(jìn)程間以及同一進(jìn)程內(nèi)不同線程之間的同步手段。 6 信號(hào)信號(hào) ( sinal ) : 信號(hào)是一種比較復(fù)雜的通信方式,,用于通知接收進(jìn)程某個(gè)事件已經(jīng)發(fā)生,。 7 共享內(nèi)存通信共享內(nèi)存( shared memory ) :共享內(nèi)存就是映射一段能被其他進(jìn)程所訪問的內(nèi)存,這段共享內(nèi)存由一個(gè)進(jìn)程創(chuàng)建,,但多個(gè)進(jìn)程都可以訪問,。共享內(nèi)存是最快的 IPC 方式,它是針對(duì)其他進(jìn)程間通信方式運(yùn)行效率低而專門設(shè)計(jì)的,。它往往與其他通信機(jī)制,,如信號(hào)兩,配合使用,,來實(shí)現(xiàn)進(jìn)程間的同步和通信,。 8 套接字通信套接字( socket ) : 套接口也是一種進(jìn)程間通信機(jī)制,與其他通信機(jī)制不同的是,,它可用于不同機(jī)器間的進(jìn)程通信,。 之前寫過一個(gè)課程設(shè)計(jì):基于Internet的Linux客戶機(jī)/服務(wù)器系統(tǒng)通訊設(shè)計(jì)與實(shí)現(xiàn) 是利用sock通信實(shí)現(xiàn)的,可以參考一下,。 通信過程如下: 8.1命名socketSOCK_STREAM 式本地套接字的通信雙方均需要具有本地地址,,其中服務(wù)器端的本地地址需要明確指定,指定方法是使用 struct sockaddr_un 類型的變量,。 8.2 綁定SOCK_STREAM 式本地套接字的通信雙方均需要具有本地地址,,其中服務(wù)器端的本地地址需要明確指定,指定方法是使用 struct sockaddr_un 類型的變量,,將相應(yīng)字段賦值,,再將其綁定在創(chuàng)建的服務(wù)器套接字上,綁定要使用 bind 系統(tǒng)調(diào)用,,其原形如下:
其中 socket表示服務(wù)器端的套接字描述符,,address 表示需要綁定的本地地址,是一個(gè) struct sockaddr_un 類型的變量,,address_len 表示該本地地址的字節(jié)長(zhǎng)度,。 8.3 監(jiān)聽服務(wù)器端套接字創(chuàng)建完畢并賦予本地地址值(名稱,本例中為Server Socket)后,,需要進(jìn)行監(jiān)聽,,等待客戶端連接并處理請(qǐng)求,監(jiān)聽使用 listen 系統(tǒng)調(diào)用,,接受客戶端連接使用accept系統(tǒng)調(diào)用,,它們的原形如下:
其中 socket 表示服務(wù)器端的套接字描述符,;backlog 表示排隊(duì)連接隊(duì)列的長(zhǎng)度(若有多個(gè)客戶端同時(shí)連接,則需要進(jìn)行排隊(duì)),;address 表示當(dāng)前連接客戶端的本地地址,,該參數(shù)為輸出參數(shù),是客戶端傳遞過來的關(guān)于自身的信息,;address_len 表示當(dāng)前連接客戶端本地地址的字節(jié)長(zhǎng)度,,這個(gè)參數(shù)既是輸入?yún)?shù),又是輸出參數(shù),。 8.4 連接服務(wù)器客戶端套接字創(chuàng)建完畢并賦予本地地址值后,,需要連接到服務(wù)器端進(jìn)行通信,讓服務(wù)器端為其提供處理服務(wù),。 對(duì)于SOCK_STREAM類型的流式套接字,,需要客戶端與服務(wù)器之間進(jìn)行連接方可使用。連接要使用 connect 系統(tǒng)調(diào)用,,其原形為
其中socket為客戶端的套接字描述符,,address表示當(dāng)前客戶端的本地地址,是一個(gè) struct sockaddr_un 類型的變量,,address_len 表示本地地址的字節(jié)長(zhǎng)度,。實(shí)現(xiàn)連接的代碼如下:
8.5 相互發(fā)送接收數(shù)據(jù)無論客戶端還是服務(wù)器,,都要和對(duì)方進(jìn)行數(shù)據(jù)上的交互,,這種交互也正是我們進(jìn)程通信的主題。一個(gè)進(jìn)程扮演客戶端的角色,,另外一個(gè)進(jìn)程扮演服務(wù)器的角色,,兩個(gè)進(jìn)程之間相互發(fā)送接收數(shù)據(jù),這就是基于本地套接字的進(jìn)程通信,。發(fā)送和接收數(shù)據(jù)要使用 write 和 read 系統(tǒng)調(diào)用,,它們的原形為:
其中 socket 為套接字描述符;len 為需要發(fā)送或需要接收的數(shù)據(jù)長(zhǎng)度,; 對(duì)于 read 系統(tǒng)調(diào)用,,buffer 是用來存放接收數(shù)據(jù)的緩沖區(qū),即接收來的數(shù)據(jù)存入其中,,是一個(gè)輸出參數(shù),; 對(duì)于 write 系統(tǒng)調(diào)用,buffer 用來存放需要發(fā)送出去的數(shù)據(jù),,即 buffer 內(nèi)的數(shù)據(jù)被發(fā)送出去,,是一個(gè)輸入?yún)?shù);返回值為已經(jīng)發(fā)送或接收的數(shù)據(jù)長(zhǎng)度,。 8.6 斷開連接交互完成后,,需要將連接斷開以節(jié)省資源,,使用close系統(tǒng)調(diào)用,其原形為:
參考資料: |
|