管道没有名字,所以只能在具有血缘关系的进程间使用,而在无名管道发展出来的有名管道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 文件来读取后才正常返回。

下面练习,分别写两个程序,一个是服务器程序,不断从管道读取客户发送的信息;另一个是客户程序,在命令行输入信息并从管道发送:

客户程序(写管道)

  1. /*fifo_write.c*/
  2. #include
  3. #include
  4. #include
  5. #include
  6. #include
  7. #include
  8. #include
  9. /*FIFO管道路径*/
  10. #define FIFO_SERVER "/tmp/myfifo"
  11. main(int argc,char** argv)
  12. {
  13. int fd = 0;
  14. char w_buf[100];
  15. int nwrite;
  16. /*打开FIFO管道*/
  17. fd=open(FIFO_SERVER,O_WRONLY|O_NONBLOCK,0);
  18. if(fd==-1)
  19. if(errno==ENXIO)
  20. printf("open error; no reading process\n");
  21. /*判断有没有参数输入*/
  22. if(argc==1)
  23. printf("Please send something\n");
  24. /*复制参数输入*/
  25. strcpy(w_buf,argv[1]);
  26. /*写到FIFO去*/
  27. if((nwrite=write(fd,w_buf,100))==-1)
  28. {
  29. if(errno==EAGAIN)
  30. printf("The FIFO has not been read yet.Please try later\n");
  31. }
  32. else
  33. /*输出写入的内容*/
  34. printf("write %s to the FIFO\n",w_buf);
  35. }

服务程序(读管道)

  1. /*fifo_read.c*/
  2. #include
  3. #include
  4. #include
  5. #include
  6. #include
  7. #include
  8. #include
  9. /*定义FIFO路径*/
  10. #define FIFO "/tmp/myfifo"
  11. main(int argc,char** argv)
  12. {
  13. char buf_r[100];
  14. int  fd;
  15. int  nread;
  16. /*创建FIFO管道*/
  17. if((mkfifo(FIFO,O_CREAT|O_EXCL)<0)&&(errno!=EEXIST))
  18. printf("cannot create fifoserver\n");
  19. printf("Preparing for reading bytes...\n");
  20. memset(buf_r,0,sizeof(buf_r));
  21. /*打开FIFO管道,不阻塞方式*/
  22. fd=open(FIFO,O_RDONLY|O_NONBLOCK,0);
  23. if(fd==-1)
  24. {
  25. perror("open");
  26. exit(1);
  27. }
  28. while(1)
  29. {
  30. memset(buf_r,0,sizeof(buf_r));
  31. /*读管道,因为定义了非阻塞方式,故在此不会阻塞进程*/
  32. if((nread=read(fd,buf_r,100))==-1){
  33. if(errno==EAGAIN)
  34. printf("no data yet\n");
  35. }
  36. printf("read %s from FIFO\n",buf_r);
  37. sleep(1);
  38. }
  39. pause();
  40. unlink(FIFO);
  41. }

接下来进行编译,编译好后,在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的更多相关文章

  1. linux进程通信

    e14: 进程间通信(进程之间发送/接收字符串/结构体): 传统的通信方式: 管道(有名管道 fifo,无名管道 pipe) 信号 signal System V(基于IPC的对象):         ...

  2. Linux学习笔记(13)-进程通信|命名管道

    匿名管道只能在具有亲属关系的进程间通信,那么如果想要在不具有亲戚关系,想在陌生人之间通信,那又该怎么办呢? 别慌,Linux身为世界上*强大的操作系统,当然提供了这种机制,那便是命名管道-- 所谓命名 ...

  3. Linux系统编程@进程通信(一)

    进程间通信概述 需要进程通信的原因: 数据传输 资源共享 通知事件 进程控制 Linux进程间通信(IPC)发展由来 Unix进程间通信 基于System V进程间通信(System V:UNIX系统 ...

  4. Linux下进程通信的八种方法

    Linux下进程通信的八种方法:管道(pipe),命名管道(FIFO),内存映射(mapped memeory),消息队列(message queue),共享内存(shared memory),信号量 ...

  5. Qt 的内部进程通信机制

    Qt 的内部进程通信机制 续欣 (xxin76@hotmail.com), 博士.大学讲师 2004 年 4 月 01 日 Qt 作为一种跨平台的基于 C++ 的 GUI 系统,能够提供给用户构造图形 ...

  6. Linux下进程通信之管道

    每个进程各自有不同的用户地址空间,任何一个进程的全局变量在另一个进程中都看不到,所以进程之间要交换数据必须通过内核,在内核中开辟一块缓冲区,进程1把数据从用户空间拷到内核缓冲区,进程2再从内核缓冲区把 ...

  7. Linux进程通信学习总结

    http://blog.csdn.net/xiaoweibeibei/article/details/6552498 SYSV子系统的相关概念   引用标识符:引用标识符是一个整数,表示每一个SYSV ...

  8. python 守护进程、同步锁、信号量、事件、进程通信Queue

    一.守护进程 1.主进程创建守护进程 其一:守护进程会在主进程代码执行结束后就终止 其二:守护进程内无法再开启子进程,否则抛出异常:AssertionError: daemonic processes ...

  9. linux下有名管道进程通信

    一.任务 1.学习mkfifo等函数: 2.了解有名管道的特点.阻塞打开与非阻塞打开等: 3.编写一个关于有名管道进程通信的程序,并运行. 二.相关概念 1.相关函数 创建有名管道的函数是mkfifo ...

随机推荐

  1. libgo协程库:网络性能完爆ASIO异步模型(-O3测试)

    在purecpp社区的github组织中有一个协程库:https://github.com/yyzybb537/libgo 近日有用户找到我,想要了解一下libgo库在网络方面的性能,于是选取已入选标 ...

  2. 主函数 main WinMain _tmain _tWinMain 的区别

    main是C/C++的标准入口函数名 WinMain是windows API窗体程序的入口函数.(int WINAPI WinMain()) 中 WINAPI是__stdcall宏,在windef.h ...

  3. 直接对寄存器操作,实现usart的串口输出寄存器的配置

    就像前面提到的,我用的板子是一款stm32f107系列的板子,在这块板子上,已经开发出了一套比较成熟的库函数,这也就意味着你可以不用直接去操作存储器来实现某些功能.比方说对于USART来说可以直接通过 ...

  4. D2 前端技术论坛总结(下)

    此篇文章不接上篇了,下午4场我就不一一介绍了,主要总结下 D2 整场下来都讲了些什么.   整场下来,就3个关键词:nodejs,多终端,工程化   nodejs 从杭js到d2,大会上提到最多的词汇 ...

  5. 请谨慎使用 @weakify 和 @strongify

    来源:酷酷的哀殿 链接:http://www.jianshu.com/p/d8035216b257 前言 相信大部分见过 @weakify 和 @strongify 的开发者都会喜欢上这两个宏.但是很 ...

  6. JavaScript 获取当前时间戳的代码

    avaScript 获取当前时间戳: 第一种方法: 复制代码代码如下: var timestamp = Date.parse(new Date());  结果:1280977330000 第二种方法: ...

  7. Mispelling4

    Problem Description Misspelling is an art form that students seem to excel at. Write a program that ...

  8. Spring MVC Controller单例陷阱

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://lavasoft.blog.51cto.com/62575/1394669 Spr ...

  9. IOS UITableView Group&Section

    UItableView 根据数据结构不同 会有不同样式 关键在两个代理 tableviewdelegate&tabledatasourse 下面代码是我实施的Group 在模拟器中 ios6. ...

  10. 在ios开发中nil和NUll和Nilde区别————和如何判断连个对象的关系和UISlider不能拖动的问题

    nil表示一个对象指针为空,针对对象 >示例代码: NSString *someString = nil; NSURL *someURL = nil; id someObject = nil; ...