LinuxC/C++程式設計(4)—管道通訊
阿新 • • 發佈:2019-01-23
管道是Linux為程序提供的一種通訊方式,這裡所說的管道只能用於有血緣關係的程序(一般是子程序和父程序之間)。一般用來做程序同步和程序間通訊。
Linux中提供的有名管道的建立函式為:int pipe(int pipe[2]);
pipe(建立管道): 1) 標頭檔案 #include<unistd.h> 2) 定義函式: int pipe(int filedes[2]); 3) 函式說明: pipe()會建立管道,並將檔案描述詞由引數filedes陣列返回。 filedes[0]為管道里的讀取端 filedes[1]則為管道的寫入端。 4) 返回值: 若成功則返回零,否則返回-1,錯誤原因存於errno中。 錯誤程式碼: EMFILE 程序已用完檔案描述詞最大量 ENFILE 系統已無檔案描述詞可用。 EFAULT 引數 filedes 陣列地址不合法。*/
對於管道的讀寫都是直接通過讀寫檔案描述符filedes完成。且預設阻塞,即管道資料滿的時候寫操作被阻塞,資料空的時候讀操作被阻塞。
下面貼一段簡單的程式碼:
#include <iostream> #include <unistd.h> #include <sys/wait.h> using namespace std; int main() { int pipefd[2]; pipe(pipefd); //包含於<unistd.h>,定義了一個管道,同時也打開了引數的檔案描述符 pid_t pid = fork(); if (pid < 0) { cerr << "fork error!" << endl; return -1; } else if (pid > 0) { cout << "I'm the parent process! Now write to the pipe!" << endl; close(pipefd[0]);//關閉管道的讀取端 char sendMsg[100] = "heiheihei";//這是要傳遞的資訊 write(pipefd[1], sendMsg, 100);//將資訊寫入管道 close(pipefd[1]);//寫完之後關閉寫入端 } else if (pid == 0) { cout << "I'm the child process!"; close(pipefd[1]);//過程和寫入是類似的 char receiveMsg[100]; read(pipefd[0], receiveMsg, 100);//如果管道為空,這個函式預設被阻塞 close(pipefd[0]); cout << "Now I've recerive the message:" << receiveMsg << endl; } waitpid(pid, NULL ,0); //包含於<sys/wait.h>,等待子程序結束並清理其資源 return 0; }
控制檯的輸出結果如下:父程序傳送的字串在子程序中列印了:
I'm the parent process! Now write to the pipe!
I'm the child process! Now I've recerive the message:heiheihei
如果要設定管道為非阻塞模式,可以通過下面兩個函式實現:
fcntl(filedes[0], F_SETFL, O_NONBLOCK);
fcntl(filedes[1], F_SETFL, O_NONBLOCK);