管道是Unix中最古老的进程间通信的形式,我们把从一个进程连接到另一个进程的一个数据流称为一个“管道”, 管道的本质是固定大小的内核缓冲区;
如:ps aux | grep httpd | awk '{print $2}'
管道限制
1)管道是半双工的,数据只能向一个方向流动;需要双方通信时,需要建立起两个管道;
2)匿名管道只能用于具有共同祖先的进程(如父进程与fork出的子进程)之间进行通信, 原因是pipe创建的是两个文件描述符, 不同进程直接无法直接获得;[通常,一个管道由一个进程创建,然后该进程调用fork,此后父子进程共享该管道]
创建一无名管道
参数
Pipefd:文件描述符数组,其中pipefd[0]表示读端,pipefd[1]表示写端
管道创建示意图

规则 1)管道空时
O_NONBLOCK disable:read调用阻塞,即进程暂停执行,一直等到有数据来到为止。
O_NONBLOCK enable:read调用返回-1,errno值为EAGAIN。
规则 2)管道满时
O_NONBLOCK disable: write调用阻塞,直到有进程读走数据
O_NONBLOCK enable:调用返回-1,errno值为EAGAIN
3)如果所有管道写端对应的文件描述符被关闭,则read返回0
4)如果所有管道读端对应的文件描述符被关闭,则write操作会产生信号SIGPIPE
Linux PIPE特征
1)当要写入的数据量不大于PIPE_BUF时,Linux将保证写入的原子性。
2)当要写入的数据量大于PIPE_BUF时,Linux将不再保证写入的原子性。
man说明:
POSIX.1-2001 says that write(2)s of less than PIPE_BUF bytes must be atomic:
the output data is written to the pipe as a contiguous sequence.
Writes of more than PIPE_BUF bytes may be nonatomic:
the kernel may interleave the data with data written by other processes.
POSIX.1-2001 requires PIPE_BUF to be at least 512 bytes.
(On Linux, PIPE_BUF is 4096 bytes. 在Linux当中, PIPE_BUF为4字节).
The precise semantics depend on whether the file descriptor is non-blocking(O_NONBLOCK),
whether there are multiple writers to the pipe, and on n, the number of bytes to be written:
O_NONBLOCK disabled(阻塞), n <= PIPE_BUF
All n bytes are written atomically; write(2) may block if there is not room for n bytes to be written immediately
O_NONBLOCK enabled(非阻塞), n <= PIPE_BUF
If there is room to write n bytes to the pipe, then write(2) succeeds immediately, writing all n bytes;
otherwise write(2) fails, with errno set to EAGAIN(注意: 如果空间不足以写入数据, 则一个字节也不写入, 直接出错返回).
O_NONBLOCK disabled, n > PIPE_BUF
The write is nonatomic: the data given to write(2) may be interleaved with write(2)s by other process;
the write(2) blocks until n bytes have been written.
O_NONBLOCK enabled, n > PIPE_BUF
If the pipe is full, then write(2) fails, with errno set to EAGAIN(此时也是没有一个字符写入管道).
Otherwise, from 1 to n bytes may be written (i.e., a "partial write" may occur;
the caller should check the return value from write(2) to see how many bytes were actually written),
and these bytes may be interleaved with writes by other processes.
附-管道容量查询
man 7 pipe
注意: 管道的容量不一定就等于PIPE_BUF, 如在Ubuntu中, 管道容量为64K, 而PIPE_BUF为4K.