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

C 語言 pipe 函數詳解:進程間通信管道機制

     編輯:關於C語言

pipe 函數概述

pipe 是 POSIX 標準提供的進程間通信(IPC)機制,創建一個單向數據管道,返回一對文件描述符:fd[0] 用於讀取,fd[1] 用於寫入。數據在內核緩衝區中流動,遵循先進先出(FIFO)原則。

函數原型與返回值

#include <unistd.h>
int pipe(int pipefd[2]);
  • 成功:返回 0,pipefd[0]、pipefd[1] 分別為讀/寫端描述符
  • 失敗:返回 -1,設置 errno(如 EMFILE、ENFILE、EFAULT)

核心特性

  1. 單向性:數據只能從寫端流向讀端
  2. 無名管道:僅限具有親緣關係的進程(父子、兄弟)使用
  3. 阻塞行為:
    • 讀端:管道為空時阻塞,直到有數據或寫端關閉
    • 寫端:管道滿時阻塞(默認 64KB),直到有空間或讀端關閉(觸發 SIGPIPE)
  4. 原子性:PIPE_BUF(≥512 字節)以內寫入保證原子

典型使用模式:父子進程通信

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>

int main() {
    int fd[2];
    if (pipe(fd) == -1) {
        perror("pipe");
        return 1;
    }

    pid_t pid = fork();
    if (pid == -1) {
        perror("fork");
        return 1;
    }

    if (pid == 0) {  // 子進程:寫入
        close(fd[0]);  // 關閉讀端
        const char* msg = "Hello from child!";
        write(fd[1], msg, strlen(msg) + 1);  // 含結束符
        close(fd[1]);  // 關閉寫端,發送 EOF
        return 0;
    } else {  // 父進程:讀取
        close(fd[1]);  // 關閉寫端
        char buf[128];
        ssize_t n = read(fd[0], buf, sizeof(buf));
        if (n > 0) {
            buf[n] = '\0';
            printf("Parent received: %s\n", buf);
        }
        close(fd[0]);
        wait(NULL);  // 回收子進程
    }
    return 0;
}

關鍵注意事項

1. 必須關閉無用端

每個進程只保留需要的描述符,務必關閉另一端。否則:

  • 讀端不關閉寫端 → 讀不到 EOF(因自己持有寫端引用)
  • 寫端不關閉讀端 → 讀端關閉時寫端收不到 SIGPIPE,持續阻塞

2. 管道容量與阻塞

Linux 管道默認 64KB。寫入超過容量會阻塞,需配合 select/poll/epoll 或非阻塞模式(O_NONBLOCK)處理高併發場景。

3. 處理 SIGPIPE

讀端關閉後寫入會觸發 SIGPIPE 導致進程終止。常見處理:

signal(SIGPIPE, SIG_IGN);  // 忽略信號,write 返回 EPIPE
// 或
int flags = fcntl(fd[1], F_GETFL);
fcntl(fd[1], F_SETFL, flags | O_NONBLOCK);  // 非阻塞模式

進階:雙向通信

需創建兩個管道:

int fd1[2], fd2[2];
pipe(fd1);  // 父→子
pipe(fd2);  // 子→父

父進程保留 fd1[1]、fd2[0];子進程保留 fd1[0]、fd2[1]。

與命名管道(FIFO)對比

特性pipe(無名管道)mkfifo(命名管道)
適用範圍親緣進程任意進程
創建方式pipe()mkfifo() + open()
持久性進程結束消失文件系統持久存在
打開阻塞無雙端打開前阻塞

總結

pipe 是 Unix 哲學「一切皆文件」的經典體現,以簡潔的文件描述符抽象實現進程間數據流傳輸。掌握其阻塞語義、描述符管理、信號處理等細節,是進行系統級編程的基礎功力。實際項目中,常配合 fork、exec、dup2 實現 Shell 管道、進程重定向等高級功能。

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