Linux 程序通訊之:管道 (Pipe)
阿新 • • 發佈:2018-11-29
一、簡介
管道(pipe) 是一種最基本的 IPC(Inter Process Communication) 機制,優點是簡單。
二、特點:
- 管道只適用於 存在血緣關係 的兩個程序之間通訊,因為只有存在血緣關係的兩個程序之間才能共享檔案描述符
- 管道分為兩端,一端讀,一端寫,有兩個檔案描述符分別表示讀端和寫端
- 管道是單向的,資料從寫端輸入,從讀端取出
- 管道的本質是一個偽檔案(實為核心緩衝區)
- 管道有容量限制,2.6.11 版本之前的 Linux 核心管道容量為 page size(4 Kb),之後版本改為 65535 位元組
- 當管道滿時,寫端將堵塞。當管道空時,讀端將堵塞
三、API 說明
1. 標頭檔案
#include <unistd.h>
2. 建立並開啟管道
int pipe(int pipefd[2]);
3. 引數說明
pipefd[0]
:讀端的檔案描述符
pipefd[1]
:寫端的檔案描述符
4. 返回值說明
成功返回 0
,失敗返回 -1
,並設定相應的 errno
。
四、示例
下面演示一個,父程序往管道寫入資料,子程序從管道讀出資料並輸出到標準輸出流。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>
int main() {
int pipe_fd[2]; // pipe_fd[0] 表示讀端,pipe_fd[1] 表示寫端
pid_t child_pid;
char buf[] = "Hello World";
if (pipe(pipe_fd) == -1) { // 建立管道
perror("pipe failed");
exit(EXIT_FAILURE);
}
child_pid = fork (); // 建立一個子程序
if (child_pid == -1) {
perror("fork failed");
exit(EXIT_FAILURE);
}
if (child_pid == 0) { // 根據 fork 的特點,child_pid 等於 0 表示子程序
close(pipe_fd[1]); // 子程序從管道讀資料,所以關閉寫端
while (read(pipe_fd[0], &buf, 1) > 0) { // 從讀端讀出資料
write(STDOUT_FILENO, &buf, 1); // 寫入到標準輸出流顯示
}
close(pipe_fd[0]);
_exit(EXIT_SUCCESS);
} else { // 根據 fork 的特點,child_pid 大於 0 表示父程序
close(pipe_fd[0]); // 父程序從管道寫資料,所以關閉讀端
write(pipe_fd[1], &buf, strlen(buf)); // 往寫端寫入資料
close(pipe_fd[1]);
wait(NULL); // 等待並回收子程序
_exit(EXIT_SUCCESS);
}
return 0;
}