1. 程式人生 > >LinuxC/C++程式設計(4)—管道通訊

LinuxC/C++程式設計(4)—管道通訊

管道是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);