管道(Pipe)
管道提供基于内核缓冲区的单向字节流通信,典型用于父子任务或线程间的数据传递。
- 源码:
- 内核对象与缓冲:
os/src/ipc/pipe.rs - VFS 文件封装:
os/src/vfs/impls/pipe_file.rs
- 内核对象与缓冲:
设计与数据路径
- 内核缓冲:通常使用环形缓冲区(参考
os/src/tool/ring_buffer.rs),在写端写入字节,在读端按序读出。 - 引用计数:读/写端在
File层分别持有到同一管道对象的引用,端点关闭逻辑据此判断 EOF/EPIPE。 - 同步与阻塞:内部维护两个
WaitQueue(读队列/写队列),在缓冲区空/满时进行睡眠与唤醒;配合调度器实现让出 CPU。
语义要点
- EOF:写端全部关闭后,读端读到缓冲区耗尽返回 0。
- EPIPE/SIGPIPE:无读者时写入返回错误,并可触发
SIGPIPE(由signal模块注入)。 - 阻塞/非阻塞:
- 阻塞读:缓冲为空则睡眠,直到有新数据或写端全部关闭。
- 阻塞写:缓冲为满则睡眠,直到有空间或读端全部关闭(报错)。
- 非阻塞模式返回类
EAGAIN/EWOULDBLOCK(具体常量以实现为准)。
- 原子性:小于等于实现规定的原子写入大小的写操作在语义上应尽量保持原子(同一写调用中的字节不被其他写穿插)。
与 VFS 的集成
pipe()创建成对的读/写端File,通过fd_table暴露为整数 fd。- 文件操作实现
read/write/poll/close等通用接口,支持被dup/fork共享。
与调度/等待队列
- 读空或写满路径进入
WaitQueue::sleep();数据到达或空间释放时wake_up_one()。 - 可中断睡眠:收到信号时从睡眠返回并携带中断错误码。
性能与边界
- 缓冲区大小固定(实现依赖),背压由写阻塞或错误返回体现。
- 内核态单次拷贝:调用方缓冲区与内核环形缓冲之间的拷贝;跨任务通信无需额外拷贝。