Linux 下管道通信

管道和消息队列本质都差不多,都是linux内核的缓冲区。

管道限制
管道是半双工的,数据只能向一个方向流动;需要双方通信时,需要建立起两个管道
只能用于具有共同祖先的进程(具有亲缘关系的进程)之间进行通信;通常,一个管道由一个进程创建,然后该进程调用fork,此后父、子进程之间就可应用该管道。管道用的是越来越少了

管道读写规

当没有数据可读时

read调用阻塞,即进程暂停执行,一直等到有数据来到为止。

如果设置了不等待,read调用返回-1,errno值为EAGAIN。

当管道满的时候

write调用阻塞,直到有进程读走数据

如果设置了不等待,调用返回-1,errno值为EAGAIN

当管道不停的被写,写满的时候

write调用阻塞

调用返回-1,errno值为EAGAIN

如果所有管道写端对应的文件描述符被关闭,则read返回

如果所有管道读端对应的文件描述符被关闭,则write操作会产生信号SIGPIPE

当要写入的数据量不大于PIPE_BUF时,linux将保证写入的原子性。

当要写入的数据量大于PIPE_BUF时,linux将不再保证写入的原子性。

 管道本质,内核中固定大小的缓冲区。

Shell脚本中的|命令本质上就是用管道技术实现的。

首先 会创建一个管道,然后有几个命令就会创建几个进程

对于执行第一个命令的进程,会关闭进程的读端,然后使用dup2命令,将标管道的写端复制成为标准输出,然后执行exec函数族,这样就相当于是对管道进行了写。对于执行第二个命令的进程,

会关闭写端,然后使用dup2命令,将管道的读端复制成为标准输出,然后执行exec函数组命令,这样第一个命令的输出就相当于是第二个命令的输入,后面多余命令都是类似的。

命名管道

管道应用的一个限制就是只能在具有共同祖先(具有亲缘关系)的进程间通信。

如果我们想在不相关的进程之间交换数据,可以使用FIFO文件来做这项工作,它经常被称为命名管道。命名管道是一种特殊类型的文件。

创建一个命名管道

命名管道可以从命令行上创建,命令行方法是使用下面这个命令:mkfifo filename

命名管道也可以从程序里创建,相关函数有: int mkfifo(const char *filename,mode_t );

猜你喜欢

转载自www.cnblogs.com/randyniu/p/9180627.html