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

C語言進程間通信:命名管道(FIFO)實現父子進程數據傳輸

     編輯:關於C

管道是進程間通信(IPC)的經典機制。本文聚焦命名管道(FIFO):它是文件系統中真實存在的特殊文件,支持無親緣關係進程通信。通過 mkfifo 創建、open/read/write/close 操作,演示父子進程雙向數據傳輸全過程。

命名管道關鍵特性

  • 文件系統實體:ls -l 可見,類型 p,如 prw-r--r--。
  • 無親緣要求:任意進程知路徑即可通信,不限父子/兄弟關係。
  • 阻塞語義:open 讀端阻塞直到寫端打開,反之亦然;read 無數據阻塞,write 緩衝區滿阻塞。
  • 半雙工:單向數據流,雙向通信需建兩個 FIFO。

核心 API

#include 
#include 

// 創建命名管道
int mkfifo(const char *pathname, mode_t mode);
// 成功返回 0,失敗 -1(errno=EEXIST 表示已存在)

// 後續按普通文件操作
int fd = open(pathname, O_RDONLY | O_WRONLY | O_NONBLOCK);
read(fd, buf, len);
write(fd, buf, len);
close(fd);

完整父子進程通信代碼

#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define FIFO_PATH "/tmp/test_fifo"
#define BUFSIZ 1024

int main() {
    char input[] = "IPC by FIFO";
    char output[BUFSIZ+1] = {0};
    int fd, count = 0;
    pid_t pid, pid_res;
    int stat_value;

    // 1. 創建命名管道
    if (mkfifo(FIFO_PATH, 0777) == -1) {
        perror("mkfifo");
        return 1;
    }

    // 2. 創建子進程
    pid = fork();
    if (pid < 0) {
        perror("fork");
        return 1;
    }

    if (pid > 0) {  // 父進程:讀取
        printf("Father running (PID=%d)\n", getpid());
        fd = open(FIFO_PATH, O_RDONLY);
        if (fd == -1) { perror("open read"); return 1; }

        pid_res = wait(&stat_value);  // 等待子進程寫入結束
        if (pid_res > 0) {
            count = read(fd, output, BUFSIZ);
            printf("Father read %d bytes: %s\n", count, output);
            close(fd);
        }
    } else {  // 子進程:寫入
        printf("Son running (PID=%d)\n", getpid());
        fd = open(FIFO_PATH, O_WRONLY);
        if (fd == -1) { perror("open write"); return 1; }

        count = write(fd, input, strlen(input));
        printf("Son wrote %d bytes: %s\n", count, input);
        close(fd);
        exit(0);
    }

    // 清理(可選,演示用)
    unlink(FIFO_PATH);
    return 0;
}

運行結果

Father running (PID=12345)
Son running (PID=12346)
Son wrote 12 bytes: IPC by FIFO
Father read 12 bytes: IPC by FIFO

關鍵時序說明

  1. 父進程 open(O_RDONLY) 會阻塞,直到子進程 open(O_WRONLY)。
  2. 子進程寫入後 close(fd),發送 EOF。
  3. 父進程 read 讀到 EOF 返回 0,或讀到數據返回字節數。
  4. 父進程用 wait 同步等待子進程退出,避免競態。

三種管道對比

類型創建通信雙方生命週期適用場景
匿名管道 pipe()內存緩衝區親緣進程(父子/兄弟)隨進程結束銷毀父子進程簡單數據流
popen() 偽管道Shell 命令管道進程與 Shell 命令隨 pclose 結束執行命令捕獲輸出
命名管道 mkfifo()文件系統特殊文件任意進程文件刪除前持久存在無親緣進程、守護進程通信

總結

命名管道(FIFO)是「有名字的管道」,以文件路徑為會合點,打破了匿名管道「親緣關係」的限制。掌握 mkfifo → open → read/write → close → unlink 標準流程,並理解阻塞 open 語義與同步機制,即可靈活實現進程間可靠數據傳輸。

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