Linux學習之旅(17) 程序間通訊

2021-09-12 07:30:47 字數 3740 閱讀 7045

程序通訊是指程序之間的資訊交換。由於程序的互斥與同步,需要在程序間交換一定的資訊,所以被稱為程序通訊,但這只是低階的程序通訊。原因在於:

(1)效率低,每次只能從緩衝區中取得乙個訊息。

(2)通訊對使用者不透明。

在程序之間要傳送大量的資料時,應當利用os提供的高階通訊工具,該工具最主要的特帶你的是:

(1)使用方便。os隱藏了實現程序通訊的具體細節,向使用者提供了一組用於實現高階通訊的命令(原語),使用者可以方便的直接利用它實現程序之間的通訊。即通訊過程對使用者是透明的。這樣就大大減少了通訊程式程式設計上的複雜性。

(2)高效的傳送大量的資料。使用者可直接利用高階通訊命令(原語)高效地傳送大量的資料。

1、共享儲存器系統(shared-memory system)

(1)基於共享資料結構的通訊方式

(2)基於共享儲存區的通訊方式

2、管道(pipe)通訊系統

「管道」是只用於連線的乙個讀程序和乙個寫程序以實現的他們的之間通訊的乙個共享檔案。因為可以在程序間傳輸大量的資料,所以被廣泛使用。

3、訊息傳遞系統(message passing system)

(1)直接通訊方式:指傳送程序利用os所提供的傳送原語,直接把訊息傳送給目標程序。

(2)簡介通訊方式:指傳送和接收程序,都共享中間實體(郵箱)的方式進行訊息的傳送和接收,完成程序間的通訊。

4、客戶機-伺服器系統(client-server system)

(1)套接字

1)基於檔案型:通訊程序都執行在一台機器上,套接字是基於本地檔案系統支援的,乙個套接字關聯到乙個特殊檔案,通訊雙方通過對這個特殊檔案的讀寫實現通訊,原理類似於管道。

2)基於網路型:通訊的雙方不在乙個主機上,通過套接字是雙方建立連線,是一種非對稱通訊。

(2)遠端過程呼叫

(3)遠端方法呼叫

1、mmap和munmap

功能:mmap可以將磁碟檔案直接對映到記憶體中,這樣就可以通過檔案指標直接操作記憶體,而不需要read和write。munmap是關閉對映的記憶體。

void* mmap(void* addr,size_t length,int prot,int flags,int fd,off_t sffset);
引數說明:

(2)length:申請空間的長度。

(3)prot:有四種取值

*prot_exec表示對映的這一段檔案,是可以執行的,例如對映共享庫。

*prot_read表示對映的這一段可讀。

*prot_write表示對映的這一段可寫。

*prot_none表示對映的這一段不可訪問。

(4)flag:一般有兩種取值

*map_shared:共享,即乙個檔案修改了記憶體後磁碟檔案也會改變。

*map_private:私有,即檔案被修改後磁碟檔案不會發生改變。

(5)fg:檔案描述符,即檔案必須被開啟。

(6)offset:偏移量,因為乙個頁面的大小為4k,所以偏移量必須是4k的整數倍。

返回值:成功返回對映的首位址,出錯則返回map_failed。當程序終止時,該程序的對映記憶體會自動解除,不過並不推薦,因為可能會造成記憶體洩漏。可以呼叫munmap()函式解除對映,munmap()成功返回0,出錯返回-1。

2、管道

(1)pipe()

(2)fifo()

int pipe(int filedes[2]);
功能:

在內存在建立一條管道。(在一段進行讀,另一端進行寫)管道是利用迴圈佇列建立的,當隊滿時,就會阻塞寫端,等待讀端讀取資料,直到佇列中有空間,寫段才允許被再次寫入。

引數說明:

(1)filedes[2]:傳出引數,pipe函式會將檔案的描述符,存在filedes在返回,其中filedes[0]為讀端的檔案描述符,而filedes[1]為寫段的檔案描述符。

返回值:0表示成功,-1表示失敗。

在利用管道進行程序間通訊時,必須確定管道的方向,即管道的一端只能讀另一端只能寫,如果允許在兩端都進行讀寫,就會引起通訊混亂和資訊丟失。那如何實現兩個程序通訊那?可以使用兩個管道。在這裡需要注意一點pipe只能在兩個有血緣關係的程序間通訊,即在pipe後通過fork函式,讓子程序繼承父程序的管道,然後進行通訊。"

#include #include #include #include #include #include #include #include int main()

printf("管道1的大小:%ld\n",fpathconf(filedis1[0],_pc_pipe_buf));

printf("管道2的大小:%ld\n",fpathconf(filedis2[0],_pc_pipe_buf));

這裡需要注意兩個程序的讀寫順序,必須是乙個程序為「先讀後寫」,另乙個為「先寫後讀」。否則就會到導致兩個程序相互等待(阻塞)。

使用管道是需要注意以下3種情況:

(1)管道寫段被關閉,讀端沒有關閉:管道中剩餘資料被讀取完後,,就會返回0。

(2)管道寫段沒有關閉,讀端也沒有關閉:管道中沒有資料,read就會被阻塞。管道中資料滿了,會使write阻塞。

(3)管道寫段沒有關閉,讀端被關閉:當寫段寫入資料時,會使寫段程序異常終止(傳送sigpipe訊號)。

可以利用fcntl函式為管道設定非阻塞(o_nonblock)。通過fpathconf(int fd,int name);可以測試管道的大小。

(2)fifo()

有名管道,解決沒有親緣關係的程序之間的通訊。建立fifo管道有兩種方式(1)利用mkfifo 命令建立。(2)使用mkfifo函式。

利用函式建立了和建立檔案是一樣。

int mkfifo(char* filename,mode_t mode);
#include #include #include #include #include #include #include #include //讀端

int main()

while(1)

}close(flags);

return 0;

}

//寫端

使用fifo需要注意:

*讀端沒有開啟,寫端回被阻塞。

*fifo支援支援雙向通訊。(pipe時單向通訊,因為父子程序共享同乙個file結構體)

*fifo可以有乙個讀端,多個寫段,也可以有乙個寫段,多個讀端。

VC 學習(17) 程序間通訊

有四種方法 1.剪貼簿 a.建立個clipboard的對話方塊應用程式,加兩editbox和兩個button傳送接收。b.具體 傳送端 if openclipboard 接收端 if openclipboard 2.匿名管道 只能在父子程序之間進行通訊 a.先建乙個parent的單文件應用程式,增加...

MFC sendmessage實現程序間通訊

用sendmessage實現程序間通訊。實現方式是傳送wm copydata訊息。傳送程式 lresult copydataresult cwnd potherwnd cwnd findwindow null,卡口管理 cstring strdatatosend 0dae12a3d8c9425daa...

Linux程序控制理論及幾種常見程序間通訊機制

1.linux程序控制理論 程序是乙個具有一定獨立功能的程式的一次執行活動 動態性 併發性 獨立性 非同步性 程序的四要素 1 有一段程式供其執行 不一定是乙個程序所專有的 就像一場戲必須有自己的劇本。2 有自己的專用系統堆疊空間 私有財產 3 有程序控制塊 task struct 有身份證,pid...