进程通信之管道

来源:互联网 发布:论文投稿要交数据吗 编辑:程序博客网 时间:2024/05/17 23:54

1. 管道

1.1管道

管道是UNIX系统IPC的最古老的形式。有下面两种局限性:

1). 历史上,它们是半双工的(即数据只能在一个方向上流动)。现在,某些系统支持全双工管道,但是为了最佳的可移植性,决不预先假定系统提供此特性

2). 它们只能在具有公共祖先的进程间使用。通常,一个管道由一个进程创建,然后进程调用fork,此后父、子进程间就有可应用该管道。

FIFO没有第二种局限性,套接字和命名流管道没有这两种局限性。

每当你在管道线中键入一个由shell执行的命令序列时,shell为每一条命令单独创建一进程,然后将前一条命令进程的标准输出用管道与后一条命令的标准输入相连接。

管道是由调用pipe函数而创建的:

#include <unistd.h>

int pipe(int filedes[2]);

经由参数filedes返回两个文件描述符:filedes[0]为读而打开,filedes[1]为写而打开。filedes[1]的输出是filedes[0]的输入。

函数fstat对管道的每一端都返回一个FIFO类型的文件描述符,可以用宏S_ISFIFO来测试管道。

通常,调用pipe的进程接着调用fork,这样就建立了从父进程到子进程(或反向)的IPC管道。对于从父进程到子进程的管道,父进程关闭管道的读端(fd[0]),子进程则关闭写端(fd[1]);对于从子进程到父进程的管道,父进程关闭管道的写端(fd[1]),子进程则关闭读端(fd[0])。

当管道的一端被关闭后,下列两条规则则起作用:

1). 当读一个写端已经关闭的管道时,在所有数据被读取后,read返回0,以表示达到了文件结束处。

2). 当写一个读端已经关闭的管道时,则产生信号SIGPIPE。如果忽略该信号或捕捉该信号并从其处理程序返回,则write返回-1,errno设置为EPIPE。

在写管道时,常量PIPE_BUF规定了内核中管道缓冲区的大小。如果对管道调用write,而且要求写的字节数小于等于PIPE_BUF,则此操作不会与其它进程对同一管道的write操作穿插进行。(用pathconf或fpath函数可以确定PIPE_BUF的值)。

1.2. 实例

在调用fork之前先创建一个管道。fork之后,父进程关闭其读端,子进程关闭其写端。子进程然后调用dup2,使其标准输入成为管道的读端。当执行分页程序时,其标准输入将是管道的读端。