首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

Linux 進程間通信實戰:基於 FIFO 的視頻數據傳輸架構與非阻塞模型

     編輯:關於C語言

場景:單服務器多客戶端視頻流分發

近期項目需在多進程間傳輸大體積視頻數據,架構為 **1 服務器 + N 客戶端**。經權衡管道、Socket、共享內存等方案,最終選擇 **FIFO (Named Pipe)**:文件系統路徑作為 rendezvous point,語義清晰,適合本地高吞吐場景。

關鍵設計決策:專屬 FIFO + 非阻塞 I/O

  • 隔離通道:服務器為每個客戶端創建獨立 FIFO (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"),直到對應客戶端啟動並打開寫端 — — 這在生產環境中是不可接受的單點故障。

FIFO 的局限與演進方向

  • 命名協商:管道名需雙方約定,缺乏服務發現機制
  • 單向半雙工:雙向通信需成對創建 FIFO
  • 本地限制:無法跨主機,分布式場景需遷移至 Unix Domain Socket 或 TCP
  • 流控缺失:視頻場景下需自行實現背壓/丟幀策略

後續規劃:引入 epoll 監聽多 FIFO 事件驅動讀取,替換輪詢;評估 splice()/vmsplice() 零拷貝優化視頻大數據傳輸路徑。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved