近期項目需在多進程間傳輸大體積視頻數據,架構為 **1 服務器 + N 客戶端**。經權衡管道、Socket、共享內存等方案,最終選擇 **FIFO (Named Pipe)**:文件系統路徑作為 rendezvous point,語義清晰,適合本地高吞吐場景。
fifo1, fifo2...),避免多路復用邏輯複雜度open(..., O_RDONLY | O_NONBLOCK) 防止服務器啟動時阻塞於無寫端的 open()read() 各 FIFO,len > 0 時處理數據#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <time.h> #include <limits.h>
int main(int argc, char** argv) {
if (argc != 2) { fprintf(stderr, "Usage: %s \n", argv[0]); exit(1); }
int fd = open(argv[1], O_WRONLY);
if (fd < 0) { perror("open"); exit(1); }
char buf[PIPE_BUF];
time_t tp;
while (1) {
time(&tp);
int len = sprintf(buf, "wrfifo: %d sends %s", getpid(), ctime(&tp));
if (write(fd, buf, len + 1) < 0) { perror("write"); break; }
sleep(1); // 控制發送頻率
}
close(fd);
return 0;
}
#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <limits.h>
int main() {
mode_t mode = 0666;
unlink("fifo1"); unlink("fifo2");
mkfifo("fifo1", mode); mkfifo("fifo2", mode);
int fd1 = open("fifo1", O_RDONLY | O_NONBLOCK);
int fd2 = open("fifo2", O_RDONLY | O_NONBLOCK);
if (fd1 < 0 || fd2 < 0) { perror("open"); exit(1); }
char buf1[PIPE_BUF], buf2[PIPE_BUF];
while (1) {
int len1 = read(fd1, buf1, PIPE_BUF - 1);
if (len1 > 0) printf("rdfifo1 read: %s", buf1);
int len2 = read(fd2, buf2, PIPE_BUF - 1);
if (len2 > 0) printf("rdfifo2 read: %s", buf2);
usleep(10000); // 降低 CPU 佔用
}
close(fd1); close(fd2);
return 0;
}
# 終端 1: ./server
# 終端 2: ./client fifo1
# 終端 3: ./client fifo2
關鍵觀察:若移除 O_NONBLOCK,服務器將阻塞於首個 open("fifo1"),直到對應客戶端啟動並打開寫端 — — 這在生產環境中是不可接受的單點故障。
後續規劃:引入 epoll 監聽多 FIFO 事件驅動讀取,替換輪詢;評估 splice()/vmsplice() 零拷貝優化視頻大數據傳輸路徑。