程序間通訊

2021-08-11 11:27:41 字數 3802 閱讀 8521

(1)匿名管道和fifo有名管道。

(2)訊息佇列、訊號量和共享儲存。

(3)套接字。

管道——匿名管道

在命令列中使用:$cat file | grep "pipe" | more。這句話用了兩個管道,分別使cat的標準輸出成為grep的標準輸入,grep的標準輸出成為more的標準輸入。

建立管道:

#include int pipe(int fdes[2]);
該函式在系統內部建立一條管道,並設定該管道使用的兩個已開啟檔案描述字於陣列fdes中。fdes[0]是輸入端,fdes[1]是輸出端。

管道的作用主要體現在父子程序間的通訊:在呼叫fork之前用pipe()建立乙個管道,那麼fork之後父子程序都能訪問這兩個檔案描述字。但是只能有乙個通訊方向,所以要關閉父子程序中各自不使用的那個描述字。

//父程序通過管道向子程序傳送資料,子程序通過管道接收父程序傳送的資料

#include#include #include #include #include #include using namespace std;

#define bufsize 100

int main()

//派生子程序

if((pid = fork()) == (pid_t)0)else

exit(exit_success);

}

popen()函式和pclose()函式

#include file *popen(const char *command, const char *mode);

int pclose(file *stream);

popen()函式在呼叫程序和命令command之間建立乙個內部半雙工管道,然後派生乙個子程序,並呼叫exec()啟動shell程式執行command給出的命令。pclose()等待由popen()執行的程序終止。

管道——命名管道(fifo)

匿名管道只能用於父子程序之間的通訊,但是用fifo特別檔案,非父子關係的程序也可以交換資料。半雙工,先進先出。命名管道本質上是不相關的程序讀寫同乙個特殊檔案。必須同時有乙個程序為讀而開啟他,另乙個程序為寫而開啟它。為讀而開啟fifo將阻塞直到另乙個程序為寫而開啟同乙個fifo,為寫而開啟fifo也同樣會阻塞直到另乙個程序為讀而開啟同乙個fifo。

建立fifo兩種方法

(1)$mknod myfifo p 或者 $mkfifo a=rw myfifo。mkfifo是專門用來建立fifo檔案的,mknod除了fifo檔案還可以建立別的特殊檔案

(2)程式中建立fifo

#include #include int mkfifo(const char *path, mode_t mode);

int mknod(const char *path, mode_t mode, dev_t dev);

mkfifo建立乙個新的fifo特別檔案,path是檔案名字,mode是許可權,取值同open函式的mode引數。

mknod建立乙個給定檔案型別的新檔案,path是檔名,mode是檔案型別,dev是裝置號,此處指定為0。

開啟fifo:open函式,注意不能以o_rdwr方式開啟fifo既讀又寫,因為fifo是半雙工的。指定o_nonblock標識,說明對該檔案的讀寫是非阻塞的,並且開啟的動作也是非阻塞的,否則open將阻塞直到另乙個程序以相反的讀寫方式開啟同乙個fifo檔案。但是對於普通檔案來說,無論是否設定o_nonblock,open均不阻塞。

//寫.cpp

int resfd=mkfifo(「c:/my_fifo」,0777); //建立命名管道

int pipefd=open(「c:/my_fifo」,o_wronly); //開啟命名管道

write(pipefd,buffer,buffer_size); //往管道中寫東西

//讀.cpp

int pipefd=open(「c:/my_fifo」,o_rdonly); //開啟已經建立的命名管道

read(pipefd,buffer,buffer_size); //往管道中讀東西

訊息佇列

i. 優點:

1. 傳輸資料塊,而不是無格式位元組流;可以有選擇的接收資料,而不是所有資料都接收(管道)

2. 沒有緩衝區大小受限這一說

3. 不相關程序通訊

4. 無管道的同步阻塞問題

ii. 缺點:

1. 訊息佇列中的訊息不接收,就會一直存在在那兒(管道在最後乙個程序引用結束後會自動刪除(至少是裡面的資料是這樣)),直至顯式的刪除訊息佇列或者刪除,接收完訊息

iii. 使用示例

//接收.程序

int msgfd=msgget((key_t)1234, 0666 | ipc_creat); //建立或獲取管道

msgrcv(msgid, (void*)&data, bufsiz, msgtype, 0); //獲取訊息

//傳送.程序

int msgfd=msgget((key_t)1234, 0666 | ipc_creat); //建立或獲取管道

msgsnd(msgid, (void*)&data, bufsiz, msgtype, 0); //傳送訊息

共享記憶體

將同一塊記憶體對映到不同程序的位址。不同程序通過操作同一塊記憶體來滿足程序間通訊的需求。因此共享記憶體上做的操作將立即反應到其他程序,所以需要使用訊號量,來同步的使用共享記憶體。

(1)mmap函式

mmap是一種記憶體對映檔案的方法,即將乙個檔案或者其它物件對映到程序的位址空間,實現檔案磁碟位址和程序虛擬位址空間中一段虛擬位址的一一對映關係。實現這樣的對映關係後,程序就可以採用指標的方式讀寫操作這一段記憶體,而系統會自動回寫髒頁面到對應的檔案磁碟上,即完成了對檔案的操作而不必再呼叫read,write等系統呼叫函式。

#include void *mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset);
該函式中的addr可以指定描述符fd應被對映到的程序內空間的起始位址。len是對映到呼叫程序位址空間中的位元組數,他從被對映檔案開頭起第offset個位元組處開始算。prot設定記憶體對映區的保護(prot_read,prot_write,prot_exec,prot_none),flag取值map_shared表示呼叫程序對被對映資料所做的修改只對該程序可見,map_private表示變動是共享的。

(2)用shmget

建立共享記憶體區(

ipc記憶體區);用

shmat

將共享記憶體區對映到具體的程序空間;用完之後,用

shmdt

撤銷對映操作。

shmid = shmget((key_t)1234, sizeof(struct shared_use_st), 0666|ipc_creat); //建立共享記憶體

void *shm = shmat(shmid, (void*)0, 0);//將共享記憶體連線到當前程序的位址空間

struct shared_use_st *shared=(struct shared_use_st*)shm;//轉換格式

strncpy(shared->text, buffer, text_sz);//就像檔案一樣寫

shmdt(shm);//把共享記憶體從當前程序中分離

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...