匿名管道(Anonymous Pipe)和有名管道(Named Pipe,也稱為FIFO)是兩種不同的程序間通訊方式,它們有以下主要區別:
- 命名和使用方式:
- 匿名管道沒有名字,只能在具有親緣關係的程序之間使用,通常是在呼叫pipe()函式後直接使用,無需其他步驟。
- 有名管道有一個檔名,它在檔案系統中有一個路徑,不限於親緣關係的程序之間使用,可以透過檔案系統路徑來訪問。它們由mkfifo()函式建立,並可以透過檔案系統進行訪問。
- 永續性:
- 匿名管道在建立它們的程序終止時自動銷燬,因此只存在於建立它們的程序生命週期內。
- 有名管道在檔案系統中存在,即使建立它們的程序終止,它們也可以被其他程序訪問,直到顯式地被刪除或檔案系統解除安裝。
- 通訊方式:
- 匿名管道只能支援單向通訊,通常是用於父子程序之間的通訊。
- 有名管道支援雙向通訊,可以被不相關的程序之間使用。
- 程序間關係:
- 匿名管道通常用於具有父子關係的程序間通訊,因為它們是透過fork()建立的子程序繼承的。
- 有名管道可以用於任意兩個程序間的通訊,只要它們能夠訪問相同的有名管道檔案。
匿名管道demo如下:
pipefd[0]只讀不寫,pipefd[1]只寫不讀
#include <stdlib.h> #include <unistd.h> #define BUFFER_SIZE 25 int main() { char buffer[BUFFER_SIZE]; int pipefd[2]; // 用於存放管道的檔案描述符,pipefd[0]表示讀取端,pipefd[1]表示寫入端 pid_t pid; // 建立管道 if (pipe(pipefd) == -1) { perror("pipe"); exit(EXIT_FAILURE); } // 建立子程序 pid = fork(); if (pid < 0) { perror("fork"); exit(EXIT_FAILURE); } if (pid > 0) { // 父程序 close(pipefd[0]); // 關閉讀取端,父程序只負責寫入資料 printf("Parent process is writing to the pipe...\n"); write(pipefd[1], "Hello from parent process!", 26); close(pipefd[1]); // 寫入完成後關閉寫入端 } else { // 子程序 close(pipefd[1]); // 關閉寫入端,子程序只負責讀取資料 printf("Child process is reading from the pipe...\n"); read(pipefd[0], buffer, BUFFER_SIZE); printf("Child process received: %s\n", buffer); close(pipefd[0]); // 讀取完成後關閉讀取端 } return 0; }
執行結果如下:
有名管道demo如下:
程序1:寫入資料到有名管道
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <sys/stat.h> #define BUFFER_SIZE 25 #define FIFO_FILE "/tmp/myfifo" int main() { char buffer[BUFFER_SIZE]; int fd; // 建立有名管道 mkfifo(FIFO_FILE, 0666); // 開啟有名管道以寫入資料 fd = open(FIFO_FILE, O_WRONLY); if (fd == -1) { perror("open"); exit(EXIT_FAILURE); } // 寫入資料到管道 printf("Process 1 is writing to the named pipe...\n"); write(fd, "Hello from Process 1!", 21); printf("Process 1 wrote: Hello from Process 1!\n"); // 關閉管道 close(fd); return 0; }
程序2:從有名管道讀取資料
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <sys/stat.h> #define BUFFER_SIZE 25 #define FIFO_FILE "/tmp/myfifo" int main() { char buffer[BUFFER_SIZE]; int fd; // 建立有名管道 mkfifo(FIFO_FILE, 0666); // 開啟有名管道以讀取資料 fd = open(FIFO_FILE, O_RDONLY); if (fd == -1) { perror("open"); exit(EXIT_FAILURE); } // 從管道中讀取資料 printf("Process 2 is reading from the named pipe...\n"); read(fd, buffer, BUFFER_SIZE); printf("Process 2 received: %s\n", buffer); // 關閉管道 close(fd); return 0; }
執行結果如下: