标签:字节流 进程间 fcntl函数 传递 内存 大小 读取 参数 队列
一.匿名管道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标志
标签:字节流 进程间 fcntl函数 传递 内存 大小 读取 参数 队列
原文地址:https://www.cnblogs.com/Lune-Qiu/p/9365073.html