1. 概述
管道没有名字,适用于有亲缘关系的进程间。
FIFO指first in first out,有一个路径名与之关联,从而允许无亲缘关系的进程间使用。亦称:命名管道named pipe。
两者都是单向数据流(半双工管道),具有随进程的持续性,数据都是先进先出,在进程间通信不需要某种形式的同步。
2.管道
#include <unistd.h>
int pipe(int fd[2]);
返回:成功0,出错-1;
返回两个文件描述符:fd[0]打开来读,fd[1]打开来写。
典型使用:
(1) 单向的
在父子进程间提供通信手段。
父进程创建管道,然后fork出自身的副本。
父进程关闭读端,用于向管道中写。
子进程关闭写端,用于从管道中读。
(2) 双向的
pipe(pipe1[2]); pipe1[0], pipe1[1]
pipe(pipe2[2]); pipe2[0], pipe2[1]
fork() == 0 {//子进程
close(pipe1[1]);
close(pipe2[0]);
}
//父进程
close(pipe1[0]);
close(pipe2[1]);
3.pipe例子
下面讲述一个客户——服务器程序。
客户发送路径名,服务器发送文件内容给客户。
#include "unp.h" void client(int, int), server(int, int); int main(void) { int pipe1[2], pipe2[2]; //创建两个管道 //也会在子进程中创建
Pipe(pipe1); Pipe(pipe2); int childid = Fork(); if (childid == 0) { //child Close(pipe1[1]); //关闭写 Close(pipe2[0]); //关闭读 server(pipe1[0], pipe2[1]); exit(0); } Close(pipe1[0]); Close(pipe2[1]); client(pipe2[0], pipe1[1]); //等待子进程终止 waitpid(childid, NULL, 0); exit(0); }
server.c代码:
#include "unp.h"
//从管道中读取文件名
//通过管道把文件发送给客户端
void server(int readfd, int writefd)
{
char buff[MAXLINE + 1];
ssize_t n = Read(readfd, buff, MAXLINE);
if (n == 0) {
err_quit("end-of-file while reading pathname");
}
buff[n] = '