当前位置:   article > 正文

fifo大小 linux,Linux基础(八)管道与FIFO

linux fifo 大小

66b52468c121889b900d4956032f1009.png

8种机械键盘轴体对比

本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选?

dc2517266bc325645aec47540422d5f4.png该系列文章为《Linux/Unix系统编程手册》的学习笔记,由于该书太过冗长,属于工具书的类别,这里对书中的一些核心内容加以提炼和整理。

书中的编程练习这里不做展示和说明。

管道是一个单向、容量有限的字节流,用来在相关进程之间传递数据。FIFO是管道的变体,他们之间的一个重要区别在于FIFO可以用于任意进程间的通信。

管道

管道有以下几个特性:是一个字节流:即拥有字节流的几个特点:管道中是不存在消息或者消息边界的概念的,可以从管道中读取任意大小的数据块,而不管写入管道的数据大小。

通过管道传输的数据是有序的,顺序为写入管道的数据顺序。

在管道中无法通过lseek()随机访问数据。

是单向的:一端用于写入,另一端用于读取。

是容量有限的:管道是一个维护在内核内存中的缓冲器,一旦管道被填满,后续的写入操作会被阻塞直到读者从管道中移除了一些数据。

管道中的读取写入行为:从管道中读取数据字节为n:若管道内数据字节p=0:若写入端没有全部关闭,读取操作将被阻塞;若写入端全部关闭,将会读到文件结束(即read()调用返回0)。

若管道内数据字节p

若管道内数据字节p>n:读取n字节。

向管道内写入数据:管道存在一个PIPE_BUF,如果写入的字节数不超过这个值,管道可以保证原子写入。如果超过这个值,内核可能会将数据分成几段来传输,如果存在多个进程写入,那么写入的数据可能会交叉。

如果写入时已经没有读取端,写入端进程将受到SIGPIPE信号,默认终止进程,write()调用也将返回EPIPE错误。

创建及使用管道

int pipe(int filedes[2]);

调用pipe()系统调用会在数组filedes中返回两个打开的文件描述符,filedes[0]用于管道的读取端,filedes[1]用于管道的写入端。

管道用于父子进程或兄弟进程间的通信,方法是在调用pipe()之后调用fork(),子进程会继承父进程的文件描述符的副本,之后一个进程应立即关闭管道写入端的文件描述符,另一个则应关闭读取端的文件描述符。

使用管道连接过滤器

ls | grepfilename

shell中常见的过滤器即采用管道实现:将前一个进程的标准输出连接到管道的写入端,将后一个进程的标准输入连接到管道的读取端,可以采用dup2()调用关闭标准输入(1)或标准输出描述符(2),并将管道的响应文件描述符复制到1和2上。这里复习一下文件I/O的知识,dup2(oldfd, newfd)系统调用会确保oldfd复制到newfd上,如果newfd已经打开,调用会关闭newfd所指的文件描述符,并忽略关闭过程中的所有错误。

多数情况下进程会默认打开0、1、2的文件描述符,但为了不依赖这个前提,复制的过程应该如下所示:

int pfd[2];

pipe(pfd);

if (pfd[1] != STDOUT_FILENO) {

dup2(pfd[1], STDOUT_FILENO);

close(pfd[1]);

}

FIFO

FIFO的作用与管道类似,不过其存在于文件系统中,打开方式与打开一个普通文件一致,这样就实现了非相关进程间的通信。

创建及使用

int mkfifo(const char *pathname, mode_t mode);

mkfifo()调用会创建一个FIFO文件,并制定其权限掩码mode。可以通过open()系统调用打开FIFO:设置O_RDONLY标记打开一个FIFO以便读取数据,open()调用将会阻塞直到另一个进程打开FIFO以写入数据。

设置O_WRONLY标记打开一个FIFO以便写入数据,open()调用将会阻塞直到另一个进程打开FIFO以读取数据。

为了防止进程打开多个FIFO时产生死锁,在打开FIFO时应设置O_NONBLOCK标记来实现非阻塞I/O。如果采用这种方式调用write()向FIFO中写入数据时,若没有相应进程打开FIFO用以读取,这个调用将会失败。

(End)

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/539433
推荐阅读
相关标签
  

闽ICP备14008679号