NetBSD 进程间通讯系统分析
2006-08-09 22:57:11 来源:WEB开发网简单的进程间通讯: 管道
管道是 UNIX 最传统, 最简单, 也是最有效的进程间通讯方法. NetBSD 处理管道的代码在 kern/sys_pipe.c, 它的读写函数作为 file 结构的 fileops 挂载, 并在 read(2), write(2) 时被调用.
管道创建
pipe(2) 的响应函数实 sys_pipe(). 它首先两次调用 pipe_create(), 第一次申请读端口将调用 pipespace() 申请一个用作缓冲区的内核地址空间 (回忆 BsdSrcUvm, submap); 第二次申请写端口则不申请空间. 这样, 我们就得到了两个 pipe 结构, 对应管道的两个端口. 把缓冲区放到 rpipe 是有道理的, 因为这样即使写端口关闭了我们还可以把剩余数据读出, 而如果读端口 (消费者) 关闭了, 写端口 (生产者) 写数据也没有意义了.
接下来 sys_pipe() 的工作就是让两个端口相连和使它们与文件接口相连. 我们分别申请读写两段对应的 file 结构, 填写返回值; 然后设置 pipe_peer 将 pipe 的两个端口相连. 所有的工作就完成了.
管道读
管道读的响应函数为 pipe_read(). 我们进入了一个常见的循环, 如果请求读的字节还没完成, 我们就继续在缓冲区取数据 (XXX. 忽略 NODIRECT 的情况, 我们得先保证我们的叙述能构建一个 可运行 的系统); 否则, 假如我们没收到文件结束讯号, 又在阻塞读状态, 我们就得等待, 等待前我们还得先唤醒控制得 select/poll 函数或者生产者 writer, 否则我们的等待是永远不会结束的.
管道写
我们再来看管道写的 pipe_write() 函数. 我们首先注意到一个比较郁闷的 rpipe 和 wpipe 的指称. 这时候的 wpipe 所指向的, 其实是 pipe(2) 创建的 rpipe, 因为我们要把数据 写到读端口让它来读. 我们还可以根据要写入的数据大小判断当前 pipe 的 buffer 是否够大, 可以随时扩充之.
更多精彩
赞助商链接