pipe的使用
管道(pipe)是POSIX标准中一种可用于进程间通信的单向数据通道。一个管道有一个写端和一个读端,数据从写端写入,从读端读取,因此读端和写端分别有一个文件描述符。
管道的读写模式可以是阻塞模式,也可以是非阻塞模式(O_NONBLOCK)。对于阻塞模式,如果管道中没有数据,那么读操作将阻塞,直到写入足够数据;如果管道已满,那么写操作将阻塞,直到读出数据留出足够空间。
管道有一个最大容量,可用pathconf(_PC_PIPE_BUF)获取。当写入的数据小于最大容量时,写入操作是原子的,内核会把数据全部写入管道;而当写入的数据大于最大容量时,则写操作不再是原子的,多个进程写的数据可能交织在一起。
用于创建管道的函数如下。
#include <unistd.h>
int pipe(int pipefd[2]);
该函数所带的参数实际上是输出参数。如果该函数成功,则返回两个文件描述符,pipefd[0]代表管道读端的文件描述符,pipefd[1]则代表管道写端的文件描述符。如果要修改管道的阻塞模式,可以用fcntl函数来实现。Linux还提供一个特有的函数pipe2,允许在创建管道时直接指定阻塞模式。该函数如下:
#define _GNU_SOURCE /* See feature_test_macros(7) */
#include <fcntl.h> /* Obtain O_* constant definitions */
#include <unistd.h>
int pipe2(int pipefd[2], int flags);
pipe函数创建的管道是匿名管道,因此只能在共享文件描述符的父子进程之间使用。Linux的man手册给出了一个例子:
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
int
main(int argc, char *argv[])
{
int pipefd[2];
pid_t cpid;
char buf;
if (argc