前一个道,这节学习命名管道。

二命名管道

无名管道仅仅能用来在父子进程或兄弟进程之间进行通信,这就给没有亲缘关系的进程之间数据的交换带来了麻烦。解决问题就是本节要学习的还有一种管道通信:命名管道。

命名管道也被称为FIFO文件,FIFO不同于管道之处在于它提供一个路径名与之关联,以FIFO的文件形式存在于文件系统中。这样,即使与FIFO的创建进程不存在亲缘关系的进程。仅仅要可以訪问该路径,就行彼此通过FIFO相互通信(可以訪问该路径的进程以及FIFO的创建进程之间),因此,通过FIFO不相关的进程也能交换数据。值得注意的是。FIFO严格遵循先进先出(first in first out)。对管道及FIFO的读总是从開始处返回数据,对它们的写则把数据加入到末尾。它们不支持诸如lseek()等文件定位操作。

http://blog.csdn.net/xiaoliangsky/article/details/40121893

1 mkfifo

int mkfifo(const char *pathname, mode_t mode);

mafifo函数创建一个FIFO,FIFO在文件系统中表现为一个文件。

pahtname 文件路径

mode 和系统调用open函数中的mode是一样的。



返回值

假设函数调用成功返回非-1。

函数调用失败返回-1。

2 命名管道操作

FIFO在文件系统中表现为一个文件,大部分的系统文件调用都能够用在FIFO上面,比方:read。open,write。close。unlink。stat等函数。可是seek等函数不能对FIFO调用。

2.1 打开命名管道

能够调用open函数打开命名管道,可是有两点要注意

1)不能以O_RDWR模式打开命名管道FIFO文件,否则其行为是没有定义的,管道是单向的。不能同一时候读写;

2)就是传递给open调用的是FIFO的路径名,而不是正常的文件

打开FIFO文件通常有四种方式:

open(pathname, O_RDONLY);//1仅仅读、堵塞模式

open(pathname, O_RDONLY | O_NONBLOCK);//2仅仅读、非堵塞模式

open(pathname, O_WRONLY);//3仅仅写、堵塞模式

open(pathname, O_WRONLY | O_NONBLOCK);//仅仅写、非堵塞模式

注意堵塞模式open打开FIFO:

1)当以堵塞、仅仅读模式打开FIFO文件时,将会堵塞,直到其它进程以写方式打开訪问文件;

2)当以堵塞、仅仅写模式打开FIFO文件时。将会堵塞,直到其它进程以读方式打开文件;

3)当以非堵塞方式(指定O_NONBLOCK)方式仅仅读打开FIFO的时候,则马上返回。当仅仅写open时,假设没有进程为读打开FIFO。则返回-1,其errno是ENXIO。

以下是一个命名管道的样例:

用命名管道实现多个进程间的通信,一个server进程负责接受多个cilent进程发来的消息

server.c代码:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <limits.h>
#include <fcntl.h>
#include <sys/stat.h> typedef struct
{
pid_t child_pid;
char message[PIPE_BUF+1];
}fifo_message; int main()
{
int fd;
const char *fifoname;
fifo_message msgbuf; fifoname = "/tmp/serverfifo"; if (access(fifoname, F_OK) == -1)
{
if (mkfifo(fifoname, 0666) == -1)
{
perror("mkfifo error\n");
exit(-1);
}
} if ((fd = open(fifoname, O_RDONLY)) == -1)//以仅仅读、堵塞模式打开
{
fprintf(stdout, "open %s failed\n", fifoname);
exit(-1);
} while (1)
{
if (read(fd, &msgbuf, sizeof(msgbuf)) < 0)
{
close(fd);
perror("read error\n");
exit(-1);
} fprintf(stdout, "message from child: %d, message: %s\n", msgbuf.child_pid, msgbuf.message);
sleep(1);
} return 0;
}

client.c的代码:

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h> struct fifo_message
{
pid_t child_pid;
char message[PIPE_BUF+1];
}; int main()
{
int fd;
const char *fifoname;
struct fifo_message msgbuf; fifoname = "/tmp/serverfifo";
if (access(fifoname, F_OK) == -1)
{
perror("access error\n");
exit(-1);
} if ((fd = open(fifoname, O_WRONLY)) < 0)//以仅仅写、堵塞模式打开
{
perror("open error\n");
} msgbuf.child_pid = getpid(); while (1)
{
printf("input the message: ");
if (fgets(msgbuf.message, sizeof(msgbuf.message), stdin) == NULL)
{
perror("fgets error or end\n");
break;
} msgbuf.message[strlen(msgbuf.message)] = '\0'; if (write(fd, &msgbuf, sizeof(msgbuf)) == -1)
{
perror("write error\n");
close(fd);
exit(-1);
}
} close(fd); return 0;
}

执行结果:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveGlhb2xpYW5nc2t5/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveGlhb2xpYW5nc2t5/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">

最新文章

  1. hibernate inverse属性的作用
  2. Try to write a script to send e-mail but failed
  3. WinForm 窗体应用程序 (初步)之二
  4. UOJ52——【UR #4】元旦激光炮
  5. wordpress安装步骤
  6. android之imgView插件的使用
  7. Java SE 6 新特性: HTTP 增强--转
  8. Web服务图片压缩,nginx+lua生成缩略图
  9. SpringTest2
  10. linux cat
  11. 编写原生JS的insertAfter函数
  12. 【Android Developers Training】 78. 序言:执行网络操作
  13. 【java设计模式】【创建模式Creational Pattern】简单工厂模式Simple Factory Pattern(静态工厂方法模式Static Factory Method Pattern)
  14. nginx 判断移动端或者PC端 进入不同域名
  15. Django Cookie和Seesion
  16. json初接触
  17. MySql 学习参考目录
  18. Java == 和 equals 区别
  19. IntelliJ IDEA快捷键:F12
  20. 基于ASP.NET WebAPI OWIN实现Self-Host项目实战

热门文章

  1. jz2440烧写开发板uboot,内核和文件系统等的相关命令
  2. java Native 方法
  3. spring MVC 如何获取session并实现传值到前台
  4. 双卡双待支持双电池 夏新N808深度评测_夏新手机评测-泡泡网
  5. 辛星和您一起手写CSS气泡
  6. Hadoop源代码导入Eclipse
  7. 数据绑定以及Container.DataItem几种方式与使用方法分析
  8. PHP - 接口 - 多接口
  9. C#面向对象2 静态类、静态成员的理解
  10. 关于如何实现程序一天只启动一次的想法(C++实现)