【无标题】无名管道

发布于:2025-08-09 ⋅ 阅读:(21) ⋅ 点赞:(0)

无名管道(Unnamed Pipe,也称为匿名管道)是 Unix/Linux 系统中最基础的进程间通信(IPC)机制之一,用于在有亲缘(亲缘)关系的进程(如父子进程、兄弟进程)之间进行单向问数据传输。

无名管道的核心特点

  1. 无标识:不像命名管道(FIFO)有文件系统中的路径标识,无名管道仅存在于内存中,进程通过文件描述符访问。
  2. 半双工:数据只能单向流动,如需双向通信需创建两个无名管道。
  3. 亲缘关系限制:仅能在父子进程、兄弟进程等有共同祖先的进程间使用(通过 fork 继承管道的文件描述符)。
  4. 面向字节流:数据按字节顺序传输,没有消息边界(类似 TCP 流)。
  5. 阻塞特性
    • 读端:管道为空时,读操作会阻塞,直到有数据写入。
    • 写端:管道满时,写操作会阻塞,直到数据被读取。
    • 若写端关闭,读端会读到 0(表示数据结束);若读端关闭,写操作会触发 SIGPIPE 信号(默认终止进程)。

无名管道的创建与使用

通过 pipe() 系统调用创建无名管道,函数原型:

#include <unistd.h>
int pipe(int pipefd[2]);
  • 参数 pipefd 是一个长度为 2 的数组,用于存储管道的两个文件描述符:
    • pipefd[0]:读端(接收数据)
    • pipefd[1]:写端(发送数据)
  • 返回值:成功返回 0,失败返回 -1 并设置 errno

使用流程(父子进程通信示例)

  1. 父进程调用 pipe() 创建管道。
  2. 父进程调用 fork() 创建子进程,子进程会继承管道的两个文件描述符。
  3. 关闭不需要的端(如父进程关闭读端,子进程关闭写端,实现父→子通信)。
  4. 通过 write() 写入数据,read() 读取数据。
  5. 通信结束后关闭管道描述符。

示例代码:

#include <stdio.h>
#include <unistd.h>
#include <string.h>

int main() {
    int pipefd[2];
    char buf[1024];
    
    // 1. 创建无名管道
    if (pipe(pipefd) == -1) {
        perror("pipe failed");
        return 1;
    }
    
    // 2. 创建子进程
    pid_t pid = fork();
    if (pid == -1) {
        perror("fork failed");
        return 1;
    }
    
    if (pid == 0) {  // 子进程:读数据
        close(pipefd[1]);  // 关闭子进程的写端(不需要)
        
        // 读取管道数据
        ssize_t n = read(pipefd[0], buf, sizeof(buf));
        if (n > 0) {
            printf("子进程收到:%.*s\n", (int)n, buf);
        }
        
        close(pipefd[0]);  // 关闭读端
        return 0;
    } else {  // 父进程:写数据
        close(pipefd[0]);  // 关闭父进程的读端(不需要)
        
        // 向管道写入数据
        const char *msg = "Hello from parent!";
        write(pipefd[1], msg, strlen(msg));
        
        close(pipefd[1]);  // 关闭写端(触发子进程读端返回0)
        return 0;
    }
}

无名管道的应用场景

  • 父子进程间的简单数据传递(如父进程向子进程传递配置参数)。
  • shell 中的管道命令(如 ls | grep "txt",通过无名管道连接 lsgrep 进程)。
  • 进程间的简单协同(如子进程完成任务后向父进程发送通知)。

与命名管道(FIFO)的核心区别

特性 无名管道(Pipe) 命名管道(FIFO)
标识方式 仅通过文件描述符,无文件路径 有文件系统路径(如 /tmp/myfifo
适用进程 仅限亲缘关系进程 任意进程(通过路径访问)
生命周期 随进程退出而销毁 存在于文件系统,需手动删除

总结:无名管道是一种轻量级的 IPC 机制,适用于亲缘进程间的简单单向通信,其设计简单、效率较高,但受限于亲缘关系和半双工特性,无法满足复杂通信场景。


网站公告

今日签到

点亮在社区的每一天
去签到