進程間通信(IPC)是系統編程的核心課題。管道和 FIFO 作為最經典的 IPC 機制,雖然簡單但極其強大,是 Unix 哲學「一切皆文件」的典型體現。
管道提供單向數據流,適用於具有親緣關係的進程(通常是父子進程)。
#include <unistd.h> int pipe(int fd[2]);
成功返回 0,fd[0] 為讀端,fd[1] 為寫端。配合 read()/write() 實現數據傳輸。
pipe() 創建管道fork() 創建子進程fd[0]),子進程關閉寫端(fd[1])需要創建兩個管道,分別處理兩個方向的數據流。
FIFO 突破了親緣關係限制,通過文件系統路徑名訪問,允許無關進程通信。
#include <sys/types.h> #include <sys/stat.h> int mkfifo(const char *pathname, mode_t mode);
mode 定義權限,常用組合:
S_IRUSR | S_IWUSR — 用戶讀寫S_IRGRP | S_IWGRP — 組讀寫S_IROTH | S_IWOTH — 其他讀寫常見定義:#define FIFO_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
#define FIFO1 "/tmp/fifo.1"
#define FIFO2 "/tmp/fifo.2"
mkfifo(FIFO1, FIFO_MODE);
mkfifo(FIFO2, FIFO_MODE);
if (fork() == 0) { // 子進程
int rd = open(FIFO1, O_RDONLY);
int wr = open(FIFO2, O_WRONLY);
// 通信邏輯...
}
| 特性 | 管道 | FIFO |
|---|---|---|
| 訪問方式 | 文件描述符 | 路徑名 |
| 進程關係 | 需親緣關係 | 無關進程可用 |
| 生命週期 | 隨進程結束銷毀 | 文件系統持久存在 |
| 適用場景 | 父子進程高速通信 | 任意進程間通信 |
SIGPIPE 信號,避免寫端斷開導致進程終止splice()/tee() 零拷貝技術理解管道與 FIFO 的異同,能幫助你在系統編程中選擇最合適的 IPC 機制,構建高效穩健的並發應用。