博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Linux 进程间通信 有名管道(fifo)
阅读量:6897 次
发布时间:2019-06-27

本文共 3033 字,大约阅读时间需要 10 分钟。

有名管道特点

1)无名管道只能用于具有亲缘关系的进程之间,这就限制了无名管道的使用范围

2)有名管道可以使互不相关的两个进程互相通信。

3)有名管道可以通过路径名来指出,并且在文件系统中可见,但内容存放在内存中

4)进程通过文件IO来操作有名管道

5)有名管道遵循先进先出规则

6)不支持如lseek() 操作

 

注意

以O_WRONLY打开管道,读阻塞
以O_RDWR打开管道,当管道中没有数据,读阻塞
//当进程用open打开有名管道用只读方式打开的话,则返回的文件描述符就代表管道的读端

创建有名管道

  int mkfifo(const char *filename, mode_t  mode)

  参数:filename 有名管道文件名(包括路径);mode 权限(读写0666)

  成功返回 0 ,失败返回-1 并设置 errno 号 errno == EEXIST 时表示该有名管道已经存在

对有名管道的操作是通过文件IO 中的open read write 等操作的

 

例子:

#include 
#include
#include
#include
#include
#include
#include
#include
int main(int argc, const char *argv[]){ char buf[50] = { 0}; if(mkfifo("./fifo",0777) != 0 ) //在当前路径下(运行程序所在的路径)创建有名管道,有名管道权限读写执行 { if(errno == EEXIST) //当该有名管道存在时,提示下 { printf("File exists\n"); } else { perror("mkfifo fail "); exit(1); } } int fd; fd = open("./fifo",O_RDWR);//读写方式打开,使用文件IO 操作有名管道 if(fd < 0) { perror("open fifo fail: "); exit(1); } write(fd,"1234567",7); read(fd,buf,7); printf("%s\n",buf); return 0;}

测试:

 

 例子:通过有名管道让两个进程实现文件的复制

 

(1)读取文件写入有名管道中

/* 功能:实现在终端上输入获取文件名,读取文件内容,写到有名管道fifo中 * */#include 
#include
#include
#include
#include
#include
#include
#include
int main(int argc, const char *argv[]){ char buf[50] = { 0}; if(mkfifo("./fifo",0777) != 0 ) //创建有名管道 { if(errno == EEXIST) { printf("File exists\n"); } else { perror("mkfifo fail "); exit(1); } } int fd_fifo,fd_file; fd_fifo = open("./fifo",O_WRONLY);//只写方式打开,管道描述符 if(fd_fifo < 0) { perror("open fifo fail: "); exit(1); } fd_file = open(argv[1],O_RDONLY);//只读方式打开,源文件进行复制到管道中 if(fd_file < 0) { perror("open source fail "); exit(1); } //循环读取文件内容 ssize_t size; while(1) { size = read(fd_file,buf,50); //文件中读取数据,返回读取到多少数据 if(size <= 0) { break; } write(fd_fifo,buf,size); } close(fd_file);//关闭读的源文件 close(fd_fifo); return 0;}

(2)读取有名管道中的数据,写入文件中实现复制

/* 功能:实现在有名管道中读取数据,写到文件中 * */#include 
#include
#include
#include
#include
#include
#include
#include
int main(int argc, const char *argv[]){ char buf[50] = { 0}; if(mkfifo("./fifo",0777) != 0 ) //创建有名管道 { if(errno == EEXIST) //有名管道存在的情况 { printf("File exists\n"); } else { perror("mkfifo fail "); exit(1); } } int fd_fifo,fd_file; //此处fd_r是指有名管道,在有名管道中读取数据,写到文件中 fd_fifo = open("./fifo",O_RDONLY);//读方式打开 if(fd_fifo < 0) { perror("open fifo fail: "); exit(1); } fd_file = open(argv[1],O_WRONLY|O_CREAT|O_TRUNC,0666);//把从有名管道中读取的数据,写到文件中,只读,没有创建,清空打开 if(fd_file < 0) { perror("fd_w open fail "); exit(1); } //fifo 中循环读取数据,然后写到文件中 ssize_t size; while(1) { size = read(fd_fifo,buf,50); //读有名管道内容,返回读取多少个数据 if(size <= 0) { break; } write(fd_file,buf,size); //写入文件中 } close(fd_fifo); close(fd_file); return 0;}

测试:此时要打开两个终端让两个进程进行通信,一个执行写操作,一个执行都操作(有名管道中有数据才可以读,且管道数据内容存在内存中)

 

转载于:https://www.cnblogs.com/electronic/p/10939770.html

你可能感兴趣的文章
SQL Server进制
查看>>
简单的编辑器
查看>>
Android 数据库管理— — —更新数据
查看>>
cmd命令
查看>>
算法笔记 --- Counting Sort
查看>>
LeetCode 88 Merge Sorted Array
查看>>
HDU 3974 Assign the task
查看>>
Java并发之(3):锁
查看>>
11.2JS笔记
查看>>
oracle11G 命令【导库数量对比】
查看>>
快速优化yum (for centos5.5)
查看>>
Qt学习之路_8(Qt中与文件目录相关操作)
查看>>
第三章数据结构小结
查看>>
Linux FTP的安装与配置
查看>>
Dynamic Host Configuration Protocol (DHCP) Services
查看>>
Android的Style的使用
查看>>
vs2010中设置qt环境的智能识别方案
查看>>
ubuntu中查看已安装软件包的方法
查看>>
安装戴尔OMSA
查看>>
开博啦
查看>>