☰
Linux进程与线程(4)
2026/10/24 7:51:40 网站建设 项目流程

Linux进程间通信‑管道(无名管道&有名管道)
一、无名管道 pipe

核心特性

  1. 只支持有亲缘关系进程通信:父子、兄弟进程。没有实体文件,仅存在内核。
  2. 单向半双工:pipe得到两个文件描述符, pipefd[0] 读端, pipefd[1] 写端。数据只能单向流动,双向通信要创建两组管道。
  3. 必须先调用 pipe() 创建管道,再 fork() ,子进程复制父进程的文件描述符,才能通信。

管道阻塞规则

  1. 管道有写端存在
  • 有数据: read 直接读出数据
  • 无数据: read 阻塞休眠,等待对方write写入数据
  1. 所有写端全部关闭
  • 有残留数据:读完现有数据
  • 无数据: read 返回0,代表读到末尾,不会阻塞
  1. 管道有读端存在
  • 缓冲区未满(管道默认64KB): write 直接写入
  • 缓冲区写满: write 阻塞,等待读端取走数据
  1. 所有读端全部关闭
  • 进程执行 write ,触发管道破裂SIGPIPE信号,程序直接异常退出。

关键点:写端、读端的打开关闭状态,直接决定read/write是阻塞、返回0还是程序崩溃。

二、有名管道 FIFO(mkfifo)

核心特性

  1. 支持任意两个进程通信,不需要亲缘关系。会在磁盘生成p类型管道文件,但磁盘不存数据,数据仍然存放在内核缓冲区。
  2. open行为特殊:必须读写两端同时打开成功,open函数才会返回;只打开一端,程序阻塞等待另一端进程打开管道。这也是写代码最容易踩坑的地方。
  3. 同样单向,双向聊天必须两条有名管道,一条A写B读,一条B写A读。

接口

int mkfifo(const char *pathname, mode_t mode);

  • pathname:管道文件路径;mode权限。
  • 返回0成功,‑1失败。

重复执行mkfifo,文件已存在会报错,可以忽略该错误,不影响后续open。

三、无名管道 vs 有名管道对比

  1. 无名管道pipe
  • 无磁盘文件;仅限亲缘进程;先pipe后fork;shell | 底层就是无名管道。
  1. 有名管道mkfifo
  • 磁盘存在管道文件;任意进程;open会阻塞;双向通信需要两组FIFO。

重点总结

  1. pipe无名管道:只能父子进程,没有实体文件,通信依赖fork复制fd。牢记4条read/write阻塞规则,SIGPIPE管道破裂是高频考点。
  2. mkfifo有名管道:任意进程可通信;open会阻塞等待两端;双向聊天必须两条管道。
  3. 管道属于字节流,不识别行,消息边界靠程序自己约定(常用 \n 换行)。
  4. 代码易错点:FIFO不要单边open,路径要完全一致,mkfifo重复调用报错可以忽略。
  5. 当所有读端关闭,继续write → SIGPIPE,进程直接退出;所有写端关闭,read返回0。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询