Linux 进程间通信 有名管道(fifo)
有名管道特点:
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 <stdio.h>
- #include <stdlib.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <errno.h>
- int main(int argc, const char *argv[])
- {
- char buf[] = {};
- if(mkfifo("./fifo",) != ) //在当前路径下(运行程序所在的路径)创建有名管道,有名管道权限读写执行
- {
- if(errno == EEXIST) //当该有名管道存在时,提示下
- {
- printf("File exists\n");
- }
- else
- {
- perror("mkfifo fail ");
- exit();
- }
- }
- int fd;
- fd = open("./fifo",O_RDWR);//读写方式打开,使用文件IO 操作有名管道
- if(fd < )
- {
- perror("open fifo fail: ");
- exit();
- }
- write(fd,"",);
- read(fd,buf,);
- printf("%s\n",buf);
- return ;
- }
测试:
例子:通过有名管道让两个进程实现文件的复制
(1)读取文件写入有名管道中
- /* 功能:实现在终端上输入获取文件名,读取文件内容,写到有名管道fifo中
- * */
- #include <stdio.h>
- #include <stdlib.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <errno.h>
- int main(int argc, const char *argv[])
- {
- char buf[] = {};
- if(mkfifo("./fifo",) != ) //创建有名管道
- {
- if(errno == EEXIST)
- {
- printf("File exists\n");
- }
- else
- {
- perror("mkfifo fail ");
- exit();
- }
- }
- int fd_fifo,fd_file;
- fd_fifo = open("./fifo",O_WRONLY);//只写方式打开,管道描述符
- if(fd_fifo < )
- {
- perror("open fifo fail: ");
- exit();
- }
- fd_file = open(argv[],O_RDONLY);//只读方式打开,源文件进行复制到管道中
- if(fd_file < )
- {
- perror("open source fail ");
- exit();
- }
- //循环读取文件内容
- ssize_t size;
- while()
- {
- size = read(fd_file,buf,); //文件中读取数据,返回读取到多少数据
- if(size <= )
- {
- break;
- }
- write(fd_fifo,buf,size);
- }
- close(fd_file);//关闭读的源文件
- close(fd_fifo);
- return ;
- }
(2)读取有名管道中的数据,写入文件中实现复制
- /* 功能:实现在有名管道中读取数据,写到文件中
- * */
- #include <stdio.h>
- #include <stdlib.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <errno.h>
- int main(int argc, const char *argv[])
- {
- char buf[] = {};
- if(mkfifo("./fifo",) != ) //创建有名管道
- {
- if(errno == EEXIST) //有名管道存在的情况
- {
- printf("File exists\n");
- }
- else
- {
- perror("mkfifo fail ");
- exit();
- }
- }
- int fd_fifo,fd_file; //此处fd_r是指有名管道,在有名管道中读取数据,写到文件中
- fd_fifo = open("./fifo",O_RDONLY);//读方式打开
- if(fd_fifo < )
- {
- perror("open fifo fail: ");
- exit();
- }
- fd_file = open(argv[],O_WRONLY|O_CREAT|O_TRUNC,);//把从有名管道中读取的数据,写到文件中,只读,没有创建,清空打开
- if(fd_file < )
- {
- perror("fd_w open fail ");
- exit();
- }
- //fifo 中循环读取数据,然后写到文件中
- ssize_t size;
- while()
- {
- size = read(fd_fifo,buf,); //读有名管道内容,返回读取多少个数据
- if(size <= )
- {
- break;
- }
- write(fd_file,buf,size); //写入文件中
- }
- close(fd_fifo);
- close(fd_file);
- return ;
- }
测试:此时要打开两个终端让两个进程进行通信,一个执行写操作,一个执行都操作(有名管道中有数据才可以读,且管道数据内容存在内存中)
Linux 进程间通信 有名管道(fifo)的更多相关文章
- linux进程间通信-有名管道(FIFO)
有名管道(FIFO) 命名管道也被称为FIFO文件,是一种特殊的文件.由于linux所有的事物都可以被视为文件,所以对命名管道的使用也就变得与文件操作非常统一. (1)创建命名管道 用如下两个函数中的 ...
- linux进程间通信--有名管道
有名管道 只有当一个库函数失败时,errno才会被设置.当函数成功运行时,errno的值不会被修改.这意味着我们不能通过测试errno的值来判断是否有错误存在.反之,只有当被调用的函数提示有错误发生时 ...
- Linux进程间通信之管道(pipe)、命名管道(FIFO)与信号(Signal)
整理自网络 Unix IPC包括:管道(pipe).命名管道(FIFO)与信号(Signal) 管道(pipe) 管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道 ...
- Linux 进程间通信之管道(pipe),(fifo)
无名管道(pipe) 管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信: 定义函数: int pipe(int f ...
- Linux进程间通信之管道
1,进程间通信 (IPC ) Inter-Process Communication 比较好理解概念的就是进程间通信就是在不同进程之间传播或交换信息. 2,linux下IPC机制的分类:管道.信号.共 ...
- Linux 进程间通信(二) 管道
Linux 进程间通信-管道 进程是一个独立的资源分配单位,不同进程之间的资源是相互独立的,没有关联,不能在一个进程中直接访问另一个进程中的资源.但是,进程不是孤立的,不同的进程之间需要信息的交换以及 ...
- 有名管道FIFO
管道和FIFO的特征之一是它们的数据是一个字节流.这是UNIX的原生I/O模型.进程往其中写入的是字节流,系统不对它作解释. FIFO不存数据,只是通过它找到内核文件. 一.建立有名管道 1.命令mk ...
- Linux -- 进程间通信之管道
管道是 Linux 里的一种文件类型,同时也是 Linux 系统下进程间通信的一种方式 创建一个管道文件有两种方式: Shell 下命令 mkfifo + filename,即创建一个有名管道 ...
- linux进程间通信之管道篇
本文是对http://www.cnblogs.com/andtt/articles/2136279.html管道一节的进一步阐释和解释 1 管道 1.1 管道简介 管道是unix系统IPC的最古老的形 ...
随机推荐
- 【足迹C++primer】47、Moving Objects(2)
版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/cutter_point/article/details/37954805 Moving Object ...
- Raspberry Pi 开机启动QT程序
https://blog.csdn.net/coekjin/article/details/52498212 https://blog.csdn.net/dubuzherui/article/deta ...
- 判断list中元素是否是相邻
private static List<Integer> findShunZi(List<Integer> tmpCards){ List<Integer> lis ...
- Sed的查,删,增,改
sed的查,删,增,改 1.sed的查找 2.sed的删除 3.sed的上下左右增加文件内容 4.sed的改
- github for windows 简单的客户端托管代码
1)创建github账户 登录https://github.com,只需用户名.注册邮箱和登录密码便能注册一个属于自己的github(之后需要到注册邮箱中进行确认,非常喜欢这种注册方式,简单而且安全) ...
- Form与ModelForm中的插件使用
一.Form插件的使用 (一)widget参数 from .models import * from django import forms from django.forms import widg ...
- 一只青蛙一次可以跳1阶或者2阶,n阶,有多少种到达终点的方式。
前两天面试遇到的一个题,当时没有想清楚,今天想了一下,po出来: # -*-encoding:utf-8-*- import sys end = 0 # 终点 cnt = 0 # 统计组合方式 def ...
- .babelrc配置例子
{ "presets":[ ["es2015",{"modlues":false}], "react", ], &quo ...
- webpack配置(使用react,es6的项目)
const path = require('path');const webpack = require('webpack');const HtmlWebpackPlugin = require('h ...
- 分布式消息中间件(二)ActiveMQ
一.概述 Apache出品,最流行的,能力强劲的开源消息总线. 1.JMS规范 Java消息服务(Java Message Service,即JMS)应用程序接口是一个Java平台中关于面向消息中间件 ...