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

二命名管道

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

命名管道也被称为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="">

linux命名管道通信过程的更多相关文章

  1. Linux学习记录--命名管道通信

    命名管道通信 什么是命名管道 一个主要的限制是,它是匿名管道的应用还没有名字,因此,只有它可以用于进程间通信的方式与亲缘关系.在命名管道(named pipe或FIFO)提出后,该限制得到了克服.FI ...

  2. C#命名管道通信

    C#命名管道通信 最近项目中要用c#进程间通信,以前常见的方法包括RMI.发消息等.但在Windows下面发消息需要有窗口,我们的程序是一个后台运行程序,发消息不试用.RMI又用的太多了,准备用管道通 ...

  3. C++和C#进程之间通过命名管道通信(上)

    C++和C#进程之间通过命名管道通信(上) "命名管道"是一种简单的进程间通信(IPC)机制.命名管道可在同一台计算机的不同进程之间,或在跨越一个网络的不同计算机的不同进程之间,支 ...

  4. c# c++通信--命名管道通信

    进程间通信有很多种,windows上面比较简单的有管道通信(匿名管道及命名管道) 最近做个本机c#界面与c++服务进行通信的一个需求.简单用命名管道通信.msdn都直接有demo,详见下方参考. c+ ...

  5. Linux 命名管道

    前文中笔者介绍了管道,本文接着介绍命名管道.文中演示所用环境为 Ubuntu 18.04 desktop. 命名管道(named pipe)又被称为先进先出队列(FIFO),是一种特殊的管道,存在于文 ...

  6. windows10使用VS(VC++)创建c++多进程命名管道通信

    代码可以在 这里 下载 代码主要涉及到: 管道通信 多线程(含临界区) 多进程通信 创建的子进程独立运行 更新日志: 04-12-2020 1. 去除自定义函数返回值,改为int作为函数返回值并增加相 ...

  7. Linux无名管道通信介绍

    Linux下无名管道一般仅用于父子进程间的通信: 测试代码如下 //file name: fifo_test.c #include <sys/prctl.h> #include " ...

  8. c#NamedPipe命名管道通信例子

    服务端 private NamedPipeServerStream pipeServer; private Thread receiveDataThread = null; public fServe ...

  9. C#使用(NamedPipe)命名管道通信的例子

    https://blog.csdn.net/yl2isoft/article/details/20228279

随机推荐

  1. BZOJ 4145: [AMPPZ2014]The Prices( 状压dp + 01背包 )

    我自己只能想出O( n*3^m )的做法....肯定会T O( nm*2^m )做法: dp( x, s ) 表示考虑了前 x 个商店, 已买的东西的集合为s. 考虑转移 : 先假设我们到第x个商店去 ...

  2. 相对路径与绝对路径构造file对象

    package file; import java.io.File; public class FileTest1 { public static void main(String[] args) { ...

  3. 02-UIKit控件、MVC

    目录: 一.控件使用 二.动态类型和静态类型 三.MVC 四.UIAlertView对话框 回到顶部 一.控件使用 1 事件源,事件处理方法有一个参数传进来,那个参数就是触发这个事件的时间源. UIS ...

  4. 演练5-1:Contoso大学校园管理1

    **演练目的:掌握复杂模型的应用程序开发. Contoso大学校园管理系统功能包括学生.课程.教师的管理. 一.创建MVC Web应用程序 显示效果如下图,操作步骤略. 二.创建数据模型 1.创建学生 ...

  5. SVN库迁移

    最后库迁移.机会主义的,在源库资源,然后上传到目标库,最后client更新url地址.的库被组长一眼识破,由于新库中没有大家的操作日志. 这次吸取上次的教训,用dump和load完毕SVN库迁移. 整 ...

  6. spring+mybatis利用interceptor(plugin)兑现数据库读写分离

    使用spring的动态路由实现数据库负载均衡 系统中存在的多台服务器是"地位相当"的,不过,同一时间他们都处于活动(Active)状态,处于负载均衡等因素考虑,数据访问请求需要在这 ...

  7. UpdatePanel和jQuery不兼容

    在做项目中发现,在使用了UpdatePanel的地方,局部刷新后,jquery失效了. 后来网上一查,才发现,jquery中的ready事件会在DOM完全加载后运行一次,而当我们实用了UpdatePa ...

  8. perl 类里的函数调用其他类的函数

    perl 类里的函数调用其他类的函数: package Horse; use base qw(Critter); sub new { my $invocant = shift; my $class = ...

  9. sharepoint 2013 根据网站模版创建网站,并赋值网站权限 create a site by custom site template

    通过程序,根据网站模版,创建新的网站 private void CreateSiteBySiteTemplate() { SPSecurity.RunWithElevatedPrivileges(de ...

  10. [Cocos2d-x开发问题-3] cocos2dx动画Animation介绍

    Cocos2d-x为了减少开发难度,对于动画的实现採用的帧动画的方案.这也就是说Cocos2d-x中的动画是帧动画. 帧动画的原理相信大家都不陌生,就是多张图片循环播放以实现动画的效果. 一个简单的动 ...