天天看点

Linux IPC实践(2) --匿名PIPE

   管道是Unix中最古老的进程间通信的形式,我们把从一个进程连接到另一个进程的一个数据流称为一个“管道”, 管道的本质是固定大小的内核缓冲区;

   如:ps aux | grep httpd | awk '{print $2}' 

管道限制

   1)管道是半双工的,数据只能向一个方向流动;需要双方通信时,需要建立起两个管道;

   2)匿名管道只能用于具有共同祖先的进程(如父进程与fork出的子进程)之间进行通信, 原因是pipe创建的是两个文件描述符, 不同进程直接无法直接获得;[通常,一个管道由一个进程创建,然后该进程调用fork,此后父子进程共享该管道]

创建一无名管道

参数

   Pipefd:文件描述符数组,其中pipefd[0]表示读端,pipefd[1]表示写端

管道创建示意图

Linux IPC实践(2) --匿名PIPE
Linux IPC实践(2) --匿名PIPE

规则 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.

Linux IPC实践(2) --匿名PIPE

附-管道容量查询

man 7 pipe

Linux IPC实践(2) --匿名PIPE

注意: 管道的容量不一定就等于PIPE_BUF, 如在Ubuntu中, 管道容量为64K, 而PIPE_BUF为4K.

继续阅读