在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
前面介绍的pipe属于匿名管道 管道的主要局限性正体现在它的特点上:
如果我们想在不相关的进程之间交换数据,可以使用FIFO文件来做这项工作,它经常被称为命名管道,是一种特殊类型的文件。 二,命名管道FIFO。2.1 有名管道相关的关键概念管 道应用的一个重大限制是它没有名字,因此,只能用于具有亲缘关系的进程间通信,在有名管道(named pipe或FIFO)提出后,该限制得到了克服。FIFO不同于管道之处在于它提供一个路径名与之关联,以FIFO的文件形式存在于文件系统中。这样,即 使与FIFO的创建进程不存在亲缘关系的进程,只要可以访问该路径,就能够彼此通过FIFO相互通信(能够访问该路径的进程以及FIFO的创建进程之 间),因此,通过FIFO不相关的进程也能交换数据。值得注意的是,FIFO严格遵循先进先出(first in first out),对管道及FIFO的读总是从开始处返回数据,对它们的写则把数据添加到末尾。它们不支持诸如lseek()等文件定位操作。 2.2有名管道的创建命名管道可以从命令行上创建,命令行方法是使用下面这个命令: $ mkfifo filename 命名管道也可以从程序里创建,相关函数有: #include <sys/types.h> 该函数的第一个参数是一个普通的路径名,也就是创建 后FIFO的名字。第二个参数与打开普通文件的open()函数中的mode 参数相同。 如果mkfifo的第一个参数是一个已经存在的路径名时,会返回EEXIST错误,所以一般典型的调用代码首先会检查是否返回该错误,如果确实返回该错 误,那么只要调用打开FIFO的函数就可以了。一般文件的I/O函数都可以用于FIFO,如close、read、write等等。 2.3有名管道的打开规则(与匿名管道一样)FIFO(命名管道)与pipe(匿名管道)之间唯一的区别在它们创建与打开的方式不同,一量这些工作完成之后,它们具有相同的语义。 man帮助说明:The only difference between pipes and FIFOs is the manner in which they are created and opened. Once these tasks have been accomplished, I/O on pipes and FIFOs has exactly the same semantics。 有名管道比管道多了一个打开操作:open。 FIFO的打开规则: 如果当前打开操作是为读而打开FIFO时,若已经有相应进程为写而打开该FIFO,则当前打开操作将成功返回;否则,可能阻塞直到有相应进程为写而打开该FIFO(当前打开操作设置了阻塞标志);或者,成功返回(当前打开操作没有设置阻塞标志)。 如果当前打开操作是为写而打开FIFO时,如果已经有相应进程为读而打开该FIFO,则当前打开操作将成功返回;否则,可能阻塞直到有相应进程为读而打开该FIFO(当前打开操作设置了阻塞标志);或者,返回ENXIO错误(当前打开操作没有设置阻塞标志)。 2.4有名管道的读写规则从FIFO中读取数据: 约定:如果一个进程为了从FIFO中读取数据而阻塞打开FIFO,那么称该进程内的读操作为设置了阻塞标志的读操作。
注:如果FIFO中有数据,则设置了阻塞标志的读操作不会因为FIFO中的字节数小于请求读的字节数而阻塞,此时,读操作会返回FIFO中现有的数据量。 向FIFO中写入数据: 约定:如果一个进程为了向FIFO中写入数据而阻塞打开FIFO,那么称该进程内的写操作为设置了阻塞标志的写操作。 对于设置了阻塞标志的写操作:
对于没有设置阻塞标志的写操作:
来看一个具体的实现: write的函数: #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <sys/stat.h> #include <sys/types.h> #include <fcntl.h>
int main(int argc, char **argv) { int infd; int fd; char buf[1024*4]; int n = 0; char *path="/home/zhf/c_prj/test.c"; char *path1="/home/zhf/c_prj/tmpfifo"; infd = open(path,O_RDONLY); if(infd == -1){ perror("open error"); exit(EXIT_FAILURE); }
if(mkfifo(path1,0644) == -1){ perror("mkfifo error"); exit(EXIT_FAILURE); } fd = open(path1,O_WRONLY); if(fd == -1){ perror("open fifo error"); exit(EXIT_FAILURE); } while((n = read(infd,buf,1024*4))){ write(fd,buf,n); } close(infd); close(fd); printf("write success\n"); return 0; } read的函数: #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <sys/stat.h> #include <sys/types.h> #include <fcntl.h>
int main(int argc, char **argv) { int outfd; int fd; char buf[1024*4]; int n = 0; char *path="/home/zhf/c_prj/tmp.txt"; char *path1="/home/zhf/c_prj/tmpfifo"; outfd = open(path,O_WRONLY | O_CREAT | O_TRUNC); if(outfd == -1){ perror("open error"); exit(EXIT_FAILURE); } fd = open(path1,O_RDONLY); if(fd == -1){ perror("open fifo error"); exit(EXIT_FAILURE); } while((n = read(fd,buf,1024*4))){ write(outfd,buf,n); } close(outfd); close(fd); printf("read success\n"); return 0; } 运行步骤: 1 首先在write函数中打开/home/zhf/c_prj/test.c文件并且建立tmpfifo文件。以写的方式打开FIFO文件 2 从test.c中读取数据存入buf数组中,并继续写入tmpfifo文件中 3 在read函数中打开/home/zhf/c_prj/tmp.txt以及tmpfifo文件,以读的方式打开FIFO文件。并将FIFO文件的数据写入tmp.txt中 运行结果
|
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论