程序間通訊

2021-09-14 06:57:39 字數 3293 閱讀 3683

即匿名管道,半雙工,只能在具有公共祖先的兩個程序間使用。fd[0]為讀而開啟,fd[1]為寫而開啟。fd[1]的輸出是fd[0]輸入。

儘管有侷限性,半雙工管道仍然是最常用的ipc形式。每當在管道中鍵入乙個命令序列,讓shell執行時,shell都會為每個命令單獨建立乙個程序,然後用管道將前一條命令程序的標準輸出與後一條命令的標準輸入相連線。

當有多個程序同時寫乙個管道(或fifo)時,常量pipe_buf說明了可被原子地寫到fifo的最大資料量。

一般用於父子程序之間通訊:

當管道的一端被關閉時:

(1)當讀乙個寫端已經被關閉的管道時,在所有資料都被讀取時,read返回0,表示檔案結束

(2)當寫乙個讀端已被關閉的管道,則產生訊號sigpipe

#include fife* popen(const cahr* cmdstring, const char* type);

返回值:若成功,返回檔案指標;若出錯,返回null

int pclose(fife* fp)

返回值:若返回cmdstring終止狀態;若出錯,返回-1

這兩個函式實現的操作是:建立乙個管道,fork乙個子程序,關閉未使用的管道端,執行乙個shell命令,然後等待命令終止。

popen:執行fork,然後呼叫exec執行cmdstring,並返回乙個標準i/o檔案指標。

//管道讀

//先建立乙個檔案test,然後再test檔案內寫入「read pipe successfully !」

#include #include int main()

;  if((fp = popen(「cat test」, 「r」)) == null)

while(fgets(buf, 200, fp) != null)

pclose(fp);

return 0;

}//列印輸出: read pipe successfully !

//管道寫:

#include 「stdio.h」

#include 「stdlib.h」

int main()

;  if((fp = popen(「cat > test1″, 「w」)) == null)

fwrite(「read pipe successfully !」, 1, sizeof(「read pipe successfully !」), fp);

pclose(fp);

return 0;

} //執行完畢後,當前目錄下多了乙個test1檔案,開啟,裡面內容為read pipe successfully !

通過fifo,不相關的程序也能交換資料。建立fifo類似於建立檔案,也有mode引數。

int mkfifo(const char *filename,mode_t mode);
mode引數指定檔案的讀寫許可權

open乙個fifo時,非阻塞標誌的影響:

用途:xsi ipc包含三種ipc:訊息佇列,訊號量,共享記憶體區

system v,是unix作業系統眾多版本中的一支(一方諸侯)。posix是由ieee 和iso/iec 開發的一簇標準。該標準用於保證編制的應用程式可以在源**一級上在多種作業系統上移植執行。

systemv ipc的問題:

訊息佇列可認為是乙個訊息鍊錶。有足夠寫許可權的執行緒可往佇列中放置訊息,有足夠讀許可權的執行緒可從佇列中取走訊息。每個訊息是乙個記錄,類似udp資料報,它由傳送者賦予乙個優先順序。

與管道和fifo的不同之處:

posix訊息佇列與systemv 訊息佇列的差別:

訊號量是乙個計數器,訊號量有三種型別:

posix訊號量不必在核心中維護,是由可能與檔案系統中的路徑名對應的名字來標識的。

訊號量、互斥鎖和條件變數之間的差異:

有名訊號量與基於記憶體的訊號量(無名訊號量)使用的函式:

posix有名訊號量。這些訊號量由乙個name引數(const char*)識別,它通常指代檔案系統中的某個檔案。而posix基於記憶體的訊號量,由應用程式分配訊號量的記憶體空間。該訊號量本身必須駐留在由所有希望共享它的程序所共享的記憶體區中。

int sem_init(sem_t *sem,int pshared,unsigned int value);

若出錯,返回-1;

當不需要使用與有名訊號量關聯的名字時,可使用基於記憶體的訊號量。彼此無血緣關係的不同程序需使用訊號量時,通常使用有名訊號量。

posix有名訊號量至少是隨核心持續的,即使當前沒有程序開啟著某個訊號量,它的值仍然保持。

基於記憶體的訊號量至少具有隨程序的持續性,然而它們真正的持續性卻取決於存放訊號量的記憶體區的型別。只要含有某個記憶體訊號量的記憶體區保持有效,該訊號量就一直存在。

systemv 訊號量通過定義計數訊號量集給訊號量增加了另外一層複雜度。除了維護乙個訊號量集內每個訊號的實際值之外,核心還給該集合中每個訊號量維護另外三個資訊:

共享記憶體區是可用ipc形式中最快的。

乙個傳遞各種訊息的客戶-伺服器檔案複製程式中涉及的通常步驟:

總共有四次資料複製,而且這四次複製是在核心和某個程序間進行的,往往開銷很大。

這些ipc形式(管道、fifo和訊息佇列)的問題在於,兩個程序要交換資訊時,這些資訊必須經由核心傳遞。通過讓兩個或多個程序共享乙個記憶體區,可以繞過上述問題。當然,這些程序必須協調或同步地對該共享記憶體區的使用。

這時,客戶–伺服器檔案複製流程為:

圖中資料中複製了兩次,注意,該共享記憶體區需同時出現在客戶和伺服器的位址空間中。

mmap提供父子間的共享記憶體區方法:

posix提供的無親緣關係程序間共享記憶體區的方法:

代之以呼叫shm_open後呼叫mmap的是,systemv共享記憶體區是先呼叫shmget,再呼叫shmat。

共享記憶體的同步、互斥

php程序間通訊 yoc PHP程序間通訊

php是用c編寫的,因此它對系統底層api的操作與c很像,同大多數語言一樣,php程序間通訊的方式有以下幾種 訊息佇列,管道,共享記憶體,socket和訊號。本文是對這幾種通訊方式對整理 管道通訊pipe 管道用於承載簡稱之間的通訊資料。為了方便理解,可以將管道比作檔案,程序a將資料寫到管道p中,然...

程序間通訊

實現程序間資料共享除了常用的記憶體檔案對映外,對於一些非檔案的資料共享可以直接使用wm copydata。如果需要在程序a傳遞資料到程序b,簡單的實現如下 在程序a中 cstring strdatatosend t hello 需要傳遞的資料 hwnd hwndreceived 程序b的接收資料視窗...

程序間通訊

最近做專案遇到奇怪的問題,我在主線程中建立乙個工作執行緒。在工作執行緒中用sendmessage向主線程傳送訊息,通知主線程操作office 物件。getactiveobject時提示 hr 0x8001010d 因為應用程式正在傳送乙個輸入同步呼叫,所以無法執行傳出的呼叫。我把sendmessag...