进程通信---FIFO
管道没有名字,所以只能在具有血缘关系的进程间使用,而在无名管道发展出来的有名管道FIFO,则有路径名与之相关联,以一种特殊设备文件形式存在于文件系统中,从而允许无亲缘关系的进程访问FIFO,下面看FIFO的详细操作
1.FIFO的建立
FIFO是存在于文件系统的文件节点,所以我们可以建立文件节点的mknod系统用来建立它,也可以mkfifo系统调用
mkfifo说明:
#include
#include
int mkfifo(char *path,mode_t mode);
说明:path:路径名,mode:指定文件存取权标志,mkfifo()会依参数pathname建立特殊的FIFO文件,该文件必须不存在,系统调用已经指定O_CREATE|O_EXCL
返回:若成功则返回0,否则返回-1,错误原因存于errno中。
错误代码
EACCESS 参数pathname所指定的目录路径无可执行的权限
EEXIST 参数pathname所指定的文件已存在。
ENAMETOOLONG 参数pathname的路径名称太长。
ENOENT 参数pathname包含的目录不存在
ENOSPC 文件系统的剩余空间不足
ENOTDIR 参数pathname路径中的目录存在但却非真正的目录。
EROFS 参数pathname指定的文件存在于只读文件系统内。
2.FIFO使用
创建后,在读写前,要先打开它,用open系统调用
当使用open()来打开 FIFO文件时,O_NONBLOCK旗标会有影响
1、当使用O_NONBLOCK 旗标时,打开FIFO 文件来读取的操作会立刻返回,但是若还没有其他进程打开FIFO 文件来读取,则写入的操作会返回ENXIO 错误代码。
2、没有使用O_NONBLOCK 旗标时,打开FIFO 来读取的操作会等到其他进程打开FIFO文件来写入才正常返回。同样地,打开FIFO文件来写入的操作会等到其他进程打开FIFO 文件来读取后才正常返回。
下面练习,分别写两个程序,一个是服务器程序,不断从管道读取客户发送的信息;另一个是客户程序,在命令行输入信息并从管道发送:
客户程序(写管道)
- /*fifo_write.c*/
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- /*FIFO管道路径*/
- #define FIFO_SERVER "/tmp/myfifo"
- main(int argc,char** argv)
- {
- int fd = 0;
- char w_buf[100];
- int nwrite;
- /*打开FIFO管道*/
- fd=open(FIFO_SERVER,O_WRONLY|O_NONBLOCK,0);
- if(fd==-1)
- if(errno==ENXIO)
- printf("open error; no reading process\n");
- /*判断有没有参数输入*/
- if(argc==1)
- printf("Please send something\n");
- /*复制参数输入*/
- strcpy(w_buf,argv[1]);
- /*写到FIFO去*/
- if((nwrite=write(fd,w_buf,100))==-1)
- {
- if(errno==EAGAIN)
- printf("The FIFO has not been read yet.Please try later\n");
- }
- else
- /*输出写入的内容*/
- printf("write %s to the FIFO\n",w_buf);
- }
服务程序(读管道)
- /*fifo_read.c*/
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- /*定义FIFO路径*/
- #define FIFO "/tmp/myfifo"
- main(int argc,char** argv)
- {
- char buf_r[100];
- int fd;
- int nread;
- /*创建FIFO管道*/
- if((mkfifo(FIFO,O_CREAT|O_EXCL)<0)&&(errno!=EEXIST))
- printf("cannot create fifoserver\n");
- printf("Preparing for reading bytes...\n");
- memset(buf_r,0,sizeof(buf_r));
- /*打开FIFO管道,不阻塞方式*/
- fd=open(FIFO,O_RDONLY|O_NONBLOCK,0);
- if(fd==-1)
- {
- perror("open");
- exit(1);
- }
- while(1)
- {
- memset(buf_r,0,sizeof(buf_r));
- /*读管道,因为定义了非阻塞方式,故在此不会阻塞进程*/
- if((nread=read(fd,buf_r,100))==-1){
- if(errno==EAGAIN)
- printf("no data yet\n");
- }
- printf("read %s from FIFO\n",buf_r);
- sleep(1);
- }
- pause();
- unlink(FIFO);
- }
接下来进行编译,编译好后,在Linux中运行两个终端,分别运行以上两个程序,可以看到,运行fifo_read时,程序一直在每隔一秒读,然后我们在另一个终端输入:
$ ./fifo_write helloworld
可以看出fifo_read显示出“helloworld”,说明接受成功
FIFO的一些注意问题:
(1)管道数据的FIFO处理方式
首先放入管道的数据,在端口首先被读出
(2)管道数据的不可再现性
已读取的数据在管道里消失,不能再读
(3)管道长度的有限性
(4)SIGPIPE信号 如果一个进程试图写入到一个没有读取到进程的管道中哦你,系统内核产生SIGPIPE信号
转自:http://blog.chinaunix.net/uid-22278460-id-1777637.html
进程通信---FIFO的更多相关文章
- linux进程通信
e14: 进程间通信(进程之间发送/接收字符串/结构体): 传统的通信方式: 管道(有名管道 fifo,无名管道 pipe) 信号 signal System V(基于IPC的对象): ...
- Linux学习笔记(13)-进程通信|命名管道
匿名管道只能在具有亲属关系的进程间通信,那么如果想要在不具有亲戚关系,想在陌生人之间通信,那又该怎么办呢? 别慌,Linux身为世界上*强大的操作系统,当然提供了这种机制,那便是命名管道-- 所谓命名 ...
- Linux系统编程@进程通信(一)
进程间通信概述 需要进程通信的原因: 数据传输 资源共享 通知事件 进程控制 Linux进程间通信(IPC)发展由来 Unix进程间通信 基于System V进程间通信(System V:UNIX系统 ...
- Linux下进程通信的八种方法
Linux下进程通信的八种方法:管道(pipe),命名管道(FIFO),内存映射(mapped memeory),消息队列(message queue),共享内存(shared memory),信号量 ...
- Qt 的内部进程通信机制
Qt 的内部进程通信机制 续欣 (xxin76@hotmail.com), 博士.大学讲师 2004 年 4 月 01 日 Qt 作为一种跨平台的基于 C++ 的 GUI 系统,能够提供给用户构造图形 ...
- Linux下进程通信之管道
每个进程各自有不同的用户地址空间,任何一个进程的全局变量在另一个进程中都看不到,所以进程之间要交换数据必须通过内核,在内核中开辟一块缓冲区,进程1把数据从用户空间拷到内核缓冲区,进程2再从内核缓冲区把 ...
- Linux进程通信学习总结
http://blog.csdn.net/xiaoweibeibei/article/details/6552498 SYSV子系统的相关概念 引用标识符:引用标识符是一个整数,表示每一个SYSV ...
- python 守护进程、同步锁、信号量、事件、进程通信Queue
一.守护进程 1.主进程创建守护进程 其一:守护进程会在主进程代码执行结束后就终止 其二:守护进程内无法再开启子进程,否则抛出异常:AssertionError: daemonic processes ...
- linux下有名管道进程通信
一.任务 1.学习mkfifo等函数: 2.了解有名管道的特点.阻塞打开与非阻塞打开等: 3.编写一个关于有名管道进程通信的程序,并运行. 二.相关概念 1.相关函数 创建有名管道的函数是mkfifo ...
随机推荐
- 当调用List Remove 失效时 [C#] .
有没有试过从一个集合里面移除一个对象之后,这个集合仍然留有这个对象?世界之大,无奇不有.稍有疏忽,便会导致这种奇怪的现象.现在让我们看看这个“不死”对象究竟是怎么一回事. 1.“不死”对象现身 这个问 ...
- Nop关键技术点概述
数据访问层 Nop.Data项目包含用于与数据库及其它数据存储交互的类和功能.Nop.Data类库帮助将数据访问逻辑和业务对象分离.Nop使用的是Entity Framework Code First ...
- [Buzz.Today]2013.07.26
# OpenFab 3D printing hardware is rapidly scaling up to output continuous mixtures of multiple mater ...
- #define用法集锦[修正版]
http://pan.baidu.com/s/1qWEuiCG
- hadoop2 作业执行过程之reduce过程
reduce阶段就是处理map的输出数据,大部分过程和map差不多 //ReduceTask.run方法开始和MapTask类似,包括initialize()初始化,根据情况看是否调用runJobCl ...
- C# mvc--ORM框架中EF的作用和特点
存放于System.Linq.QueryAble 静态类中 并且所有的扩展方法扩展自 IqueryAble<TSource>泛型接口上 用途: 接收lambda表达式 利用EF生成对应的s ...
- GCT考试如何准备
备战考试篇 回首连续的3个月的那段复习过程,感受颇多颇深!以下就各科复习,我谈谈自己的感受和经验: 语文复习: 语文主要是考察你的文学功底和素养以及已经具备的工作生活的常识.从03,04两年的考试真题 ...
- 查找字符对应Unicode码的十进制数字
//将字符转换为Unicode码中字符对应十进制数字 int byte0 = 'A' & 0xff;//byte0=65 参考文档:http://baike.baidu.com/view/26 ...
- Communications link failure的解决办法
使用Connector/J连接MySQL数据库,程序运行较长时间后就会报以下错误: Communications link failure,The last packet successfully r ...
- 常用排序算法之JavaScript实现
1.插入排序 1)算法简介 插入排序(Insertion-Sort)的算法描述是一种简单直观的排序算法.它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从 后向前扫描,找到相应位置并插入 ...