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);

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章