关于UNIX环境高级编程和UNIX网络编程的学习记录和总结
前言
管道是UNIX IPC(InterProcess Communication)的最老形式,并且所有UNIX系统都提供此种通信机制,管道有两种限制;
(1) 它们是半双工的。数据只能在一个方向上流动。
(2) 它们只能在具有公共祖先的进程之间使用。通常,一个管道由一个进程创建,然后该
进程调用fork,此后父、子进程之间就可应用该管道。
流管道没有第一种限制, FIFO和命名流管道则没有第二种限制。
管道基本是最简单的进程间通信方式
一、pipe()
管道:
在内核中借助环形队列机制,使用内核缓冲区实现。 管道是一种伪文件
管道常见的形式:
管道的特点:管道中的数据只能一次读取, 数据在管道中只能单向流动。 不能在一端同时读写。管道pipe()只用在血缘关系进程间。
pipe()原型:
int pipe(int pipefd[2]);
int pipe2(int pipefd[2], int flags); //If flags is 0, then pipe2() is the same as pipe().
参数: fd[0]: 读端。
fd[1]: 写端。
返回值: 成功: 0
失败: -1 设置errno
读管道:
1. 管道有数据,read返回实际读到的字节数。
2. 管道无数据: 1)无写端,read返回0 (类似读到文件尾)
2)有写端,read阻塞等待。
写管道:
1. 无读端, 异常终止。 (SIGPIPE导致的)
2. 有读端: 1) 管道已满, 阻塞等待
2) 管道未满, 返回写出的字节个数。
pipe()的使用
尽管管道是由单个进程创建的,却很少在单个进程间使用。管道的典型用途是为两个不同的进程提供进程间的通信。
管道的一端只能占用读或写,因此在使用时需在一端关闭读端(或写端),而在另一端关闭写端(或读端)。
如:父子进程使用pipe(),父写子读
在调用fork之前先创建一个管道。 fork之后父进程关闭其读端,子进程关闭其写端。
ret = pipe(fd); // 父进程先创建一个管道,持有管道的读端和写端
...
pid = fork(); // 子进程同样持有管道的读和写端
if (pid > 0) {
close(fd[0]); // 关闭读段
//sleep(3);
write