linux下的FIFO机制
2015-09-10 16:50
531 查看
linux下的一切操作都是文件操作,而FIFO操作也是其中的一类文件操作,想要了解FIFO操作的原理,首先需要了解管道的原理。
管道是Linux中很重要的一种通信方式,是把一个程序的输出直接连接到另一个程序的输入,常说的管道多是指无名管道,无名管道只能用于具有亲缘关系的进程之间,这是它与有名管道的最大区别。管道实现的源代码在fs/pipe.c中,在pipe.c中有很多函数,其中有两个函数比较重要,即管道读函数pipe_read()和管道写函数pipe_wrtie()。
了解管道,从下面这个例程开始:linux进程间通信之管道
若带阻塞的读取,则需要等待有写入才能引发中断完成该操作,否则将阻塞FIFO的输出一直等待;不带阻塞的读取在FIFO文件为空时则将返回0的结果;
若带阻塞的写入,则要求必须以原子操作为单位进行写入,争取一次性写完;由于每次写入的存在上限,若小于上限,则一次性完成,若大于上限,等待下一次空闲的缓冲区域继续写入,写完再返回;不带阻塞的写入则只写一次,缓冲区域一次能写完,返回写入字节数,一次不能写完,返回错误,提醒下次再写;
FIFO管道例程:FIFO系统编程之命名管道(FIFO) 此中为经典例程,通过FIFO管道完成文件的复制
FIFO管道依赖于文件描述符(fd),正常的FIFO使用过程为:
1)建立FIFO管道mkfifo(name,mode):mkfifo函数 (注意:头文件不能忘掉)
2)打开FIFO管道open(name,mode);FIFO的打开与读写规则
3)读bytes_write = write(to_fd, ptr, bytes_read)或写bytes_read = read(from_fd, buffer, BUFFER_SIZE); linux下文件的读写操作
现贴出文件复制的代码,由于针对固定FIFO管道,因此在读取的时候将FIFO管道的名称作为第三个参数,第二个参数仍然为读取后得到的文件名称;同时附程序下载渠道:(FIFO读写文件)
创建打开FIFO并将文件中的字符串写入FIFO:
管道是Linux中很重要的一种通信方式,是把一个程序的输出直接连接到另一个程序的输入,常说的管道多是指无名管道,无名管道只能用于具有亲缘关系的进程之间,这是它与有名管道的最大区别。管道实现的源代码在fs/pipe.c中,在pipe.c中有很多函数,其中有两个函数比较重要,即管道读函数pipe_read()和管道写函数pipe_wrtie()。
了解管道,从下面这个例程开始:linux进程间通信之管道
#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <fcntl.h> int main(void) { int fds[2]; //两个文件描述符,用以表示:写入方fd==PIPE==读取方,fds[0]用于读出数据,读取时必须关闭写入端,即close(fds[1]);fds[1]用于写入数据,写入时必须关闭读取端,即close(fds[0]) if(pipe(fds) == -1){ //pipe(fds)是指建立管道获取到一对文件描述符,建立成功返回0,建立失败返回-1 perror("pipe error"); exit(EXIT_FAILURE); } pid_t pid; pid = fork();//父进程将文件描述符复制给子进程 if(pid == -1){ perror("fork error"); exit(EXIT_FAILURE); } if(pid == 0){//子进程写 close(fds[0]);//子进程关闭读端 sleep(10); write(fds[1],"hello",5); exit(EXIT_SUCCESS); }else//父进程要读管道中的内容 close(fds[1]);//父进程关闭写端 char buf[10] = {0}; read(fds[0],buf,10);//父进程读 printf("receive datas = %s\n",buf); return 0; }由此可见,管道的运行过程依靠一对文件描述符,于是存在单发单收的情况,双方呈现出父子进程配对的状态,为此,FIFO提出解决了单发单收的问题,以FIFO文件的位置作为介质,两个进程可以对FIFO文件完成对应的读写操作。由于可能会有多个线程同时争取读写的权利,因此,FIFO引入了阻塞的概念:
若带阻塞的读取,则需要等待有写入才能引发中断完成该操作,否则将阻塞FIFO的输出一直等待;不带阻塞的读取在FIFO文件为空时则将返回0的结果;
若带阻塞的写入,则要求必须以原子操作为单位进行写入,争取一次性写完;由于每次写入的存在上限,若小于上限,则一次性完成,若大于上限,等待下一次空闲的缓冲区域继续写入,写完再返回;不带阻塞的写入则只写一次,缓冲区域一次能写完,返回写入字节数,一次不能写完,返回错误,提醒下次再写;
FIFO管道例程:FIFO系统编程之命名管道(FIFO) 此中为经典例程,通过FIFO管道完成文件的复制
FIFO管道依赖于文件描述符(fd),正常的FIFO使用过程为:
1)建立FIFO管道mkfifo(name,mode):mkfifo函数 (注意:头文件不能忘掉)
2)打开FIFO管道open(name,mode);FIFO的打开与读写规则
3)读bytes_write = write(to_fd, ptr, bytes_read)或写bytes_read = read(from_fd, buffer, BUFFER_SIZE); linux下文件的读写操作
现贴出文件复制的代码,由于针对固定FIFO管道,因此在读取的时候将FIFO管道的名称作为第三个参数,第二个参数仍然为读取后得到的文件名称;同时附程序下载渠道:(FIFO读写文件)
创建打开FIFO并将文件中的字符串写入FIFO:
#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) { if(argc != 2){ fprintf(stderr,"usage:%s srcfile\n",argv[0]); exit(EXIT_FAILURE); } int infd; infd = open(argv[1],O_RDONLY); if(infd == -1){ perror("open error"); exit(EXIT_FAILURE); } if(mkfifo("tmpfifo",0644) == -1){ perror("mkfifo error"); exit(EXIT_FAILURE); } int fd ; fd = open("tmpfifo",O_WRONLY); if(fd == -1){ perror("open error"); exit(EXIT_FAILURE); } char buf[1024*4]; int n = 0; while((n = read(infd,buf,1024*4))){ write(fd,buf,n); } close(infd); close(fd); printf("write success\n"); return 0; }打开FIFO读取FIFO中的字符串,放入新文件中:
#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) { if(argc != 3){ fprintf(stderr,"usage:%s desfile\n",argv[0]); exit(EXIT_FAILURE); } int outfd; outfd = open(argv[1],O_WRONLY|O_CREAT|O_TRUNC); if(outfd == -1){ perror("open error"); exit(EXIT_FAILURE); } int fd ; fd = open(argv[2],O_RDONLY); if(fd == -1){ perror("open error"); exit(EXIT_FAILURE); } char buf[1024*4]; int n = 0; while((n = read(fd,buf,1024*4))){ write(outfd,buf,n); } close(fd); close(outfd); unlink(argv[2]); printf("read success\n"); return 0; }
相关文章推荐
- Centos/Linux下如何查看网关地址/Gateway地址
- Linux多线程(转)
- linux下如何从终端打开文件夹,并且获取管理员权限
- 深刻理解Linux进程间通信(IPC)
- 个人学习笔记---软中断(下半部)和软件中断(系统调用)的区别
- Linux vmstat命令实战详解
- virualbox 复制linux,启用网卡报错:device "eth0" does not seem to be present, delaying initialization
- linux safe-rm
- Linux iostat监测IO状态
- Linux服务器定时备份脚本
- Ubuntu与Windows双系统安装流程
- 使用过的Linux命令
- Linux 内核的排队自旋锁(FIFO Ticket Spinlock)
- 虚拟机VMware安装ArchLinux
- LINUX下动态库及版本号控制
- 一个计时类,可以同时用在windows 和 linux 环境下
- ARM板烧录LinuxQt程序步骤
- 如何查看系统是 centos 还是 redhat
- linux yum-updatesd进程占用内存过多
- [部署]CentOS yum源