linux命名管道通信过程
前一个道,这节学习命名管道。
二命名管道
无名管道仅仅能用来在父子进程或兄弟进程之间进行通信,这就给没有亲缘关系的进程之间数据的交换带来了麻烦。解决问题就是本节要学习的还有一种管道通信:命名管道。
命名管道也被称为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命名管道通信过程的更多相关文章
- Linux学习记录--命名管道通信
命名管道通信 什么是命名管道 一个主要的限制是,它是匿名管道的应用还没有名字,因此,只有它可以用于进程间通信的方式与亲缘关系.在命名管道(named pipe或FIFO)提出后,该限制得到了克服.FI ...
- C#命名管道通信
C#命名管道通信 最近项目中要用c#进程间通信,以前常见的方法包括RMI.发消息等.但在Windows下面发消息需要有窗口,我们的程序是一个后台运行程序,发消息不试用.RMI又用的太多了,准备用管道通 ...
- C++和C#进程之间通过命名管道通信(上)
C++和C#进程之间通过命名管道通信(上) "命名管道"是一种简单的进程间通信(IPC)机制.命名管道可在同一台计算机的不同进程之间,或在跨越一个网络的不同计算机的不同进程之间,支 ...
- c# c++通信--命名管道通信
进程间通信有很多种,windows上面比较简单的有管道通信(匿名管道及命名管道) 最近做个本机c#界面与c++服务进行通信的一个需求.简单用命名管道通信.msdn都直接有demo,详见下方参考. c+ ...
- Linux 命名管道
前文中笔者介绍了管道,本文接着介绍命名管道.文中演示所用环境为 Ubuntu 18.04 desktop. 命名管道(named pipe)又被称为先进先出队列(FIFO),是一种特殊的管道,存在于文 ...
- windows10使用VS(VC++)创建c++多进程命名管道通信
代码可以在 这里 下载 代码主要涉及到: 管道通信 多线程(含临界区) 多进程通信 创建的子进程独立运行 更新日志: 04-12-2020 1. 去除自定义函数返回值,改为int作为函数返回值并增加相 ...
- Linux无名管道通信介绍
Linux下无名管道一般仅用于父子进程间的通信: 测试代码如下 //file name: fifo_test.c #include <sys/prctl.h> #include " ...
- c#NamedPipe命名管道通信例子
服务端 private NamedPipeServerStream pipeServer; private Thread receiveDataThread = null; public fServe ...
- C#使用(NamedPipe)命名管道通信的例子
https://blog.csdn.net/yl2isoft/article/details/20228279
随机推荐
- arm:c语言和汇编混合编程
仅作演示. 1.C和汇编可相互调用,汇编子函数格式参考 汇编:普通的函数调用的汇编代码解析 http://www.cnblogs.com/mylinux/p/4139972.html 本文演示了 : ...
- Python常用模块中常用内置函数的具体介绍
Python作为计算机语言中常用的语言,它具有十分强大的功能,但是你知道Python常用模块I的内置模块中常用内置函数都包括哪些具体的函数吗?以下的文章就是对Python常用模块I的内置模块的常用内置 ...
- mysql 如何修改、添加、删除表主键
在我们使用mysql的时候,有时会遇到须要更改或者删除mysql的主键,我们能够简单的使用alter table table_name drop primary key;来完成.以下我使用数据表tab ...
- Windows下sass的安装
sass依赖Ruby,所以,首先得先安装个Ruby 安装步骤: 1.安装Ruby的时候,勾上Add Ruby executables to your PATH(添加环境变量) 2.安装好Ruby之后, ...
- fcntl()
fcntl() F_GETFL--------------------------------------------- 将文件状态标志作为函数值返回. 文件状态标志: ...
- NVelocity 实例
using System; using System.IO; using System.Collections; using System.Collections.Generic; using Sys ...
- Spring注入静态变量(转)
今天碰到一个问题,我的一个工具类提供了几种静态方法,静态方法需要另外一个类的实例提供处理,因此就写出了这样的代码: Class Util{ private static XXX xxx; xxx = ...
- dump json 显示中文问题
[root@dr-mysql01 ~]# cat a2.pl my $url="http://192.168.32.101:3000/api/getcode?env=zj&phone ...
- 基于visual Studio2013解决C语言竞赛题之1040因数分解
题目 解决代码及点评 /* 将一个数M分解为质因数(M≠0). */ #include <stdio.h> #include <stdlib.h> void main() ...
- SRM589 DV1 250 回文字符串
其实这道题挺简单的,不过刚开始我钻了一个错误的死胡同.想明白之后才发现. 题目要求用最少的时间来将一个字符串变成回文字符串.(具体题目参看topcoder srm589 DV1 250分值的题目,不便 ...