匿名管道

一.匿名管道pipe

   #include <unistd.h>

    int pipe(int filedes[2]);

管道作用于有血缘关系的进程之间,通过fork来传递 

调用pipe函数时在内核中开辟一块缓冲区(称为管道)用于通信,它有一个读端一个写端,然后通过filedes参数传出给用户程序两个文件描述符,filedes[0]指向管道的读端,filedes[1]指向管道的写端(很好记,就像0是标准输入1是标准输出一样)。所以管道在用户程序看起来就像一个打开的文件,通过read(filedes[0]);或者write(filedes[1]);向这个文件读写数据其实是在读写内核缓冲区。pipe函数调用成功返回0,调用失败返 回-1。

     1.父进程调用pipe开辟管道,得到两个文件描述符指向管道的两端。

     2.父进程调用fork创建子进程,那么子进程也有两个文件描述符指向同一管道。

     3.父进程关闭管道读端,子进程关闭管道写端。父进程可以往管道里写,子进程可以从管道里读,管道是用环形队列实现的,数据从写端流入从读端流出,这样就实现了进程间通信。

使用管道需要注意以下4种特殊情况(假设都是阻塞I/O操作,没有设置O_NONBLOCK标 志): 

1.写端关闭,读端将剩余数据读出后,再read会返回0

2.写端未关闭,读端将剩余数据读出后,再次read会阻塞,直到管道中有数据可读了才读取数据并返回

3.读端都关闭了,写端write,那么该进程会收到信号SIGPIPE,通常会导致进程异常终止。

4.读端未关闭,但未read,那么在管道被写满时再次write会阻塞,直到管道中有空位置了才写入数据并返回。

管道的主要局限性正体现在它的特点上:

1.    只支持单向数据流;

2.    只能用于具有亲缘关系的进程之间;

3.    没有名字;

4.    管道的缓冲区是有限的(管道制存在于内存中,在管道创建时,为缓冲区分配一个页面大小);

5.    管道所传送的是无格式字节流,这就要求管道的读出方和写入方必须事先约定好数据的格式,比如多少字节算作一个消息(或命令、或记录)等等

默认创建的为阻塞管道

如果想设置为非阻塞管道, fcntl函数设置O_NONBLOCK标志 

猜你喜欢

转载自www.cnblogs.com/Lune-Qiu/p/9365073.html