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