都说python 有名管道道是通过文件来通讯的,那这个文件保存在哪里?比如说CMD程序

linux进程间通信2——有名管道
linux进程间通信2——有名管道
编辑:www.fx114.net
本篇文章主要介绍了"linux进程间通信2——有名管道",主要涉及到linux进程间通信2——有名管道方面的内容,对于linux进程间通信2——有名管道感兴趣的同学可以参考一下。
mkfifo函数的作用是在文件系统中创建一个文件,该文件用于提供功能,即命名管道。前边讲的那些管道都没有名字,因此它们被称为匿名管道,或简称管道。对文件系统来说,匿名管道是不可见的,它的作用仅限于在父进程和子进程两个进程间进行通信。而命名管道是一个可见的文件,因此,它可以用于任何两个进程之间的通信,不管这两个进程是不是父子进程,也不管这两个进程之间有没有关系。
1、创建有名管道
Mkfifo函数的原型如下所示:
#include&&sys/types.h&&
#include&&sys/stat.h&&
int&mkfifo(&const&char&*pathname,&mode_t&mode&);
mkfifo函数需要两个参数,第一个参数()是将要在文件系统中创建的一个专用文件。第二个参数()用来规定的读写权限。mkfifo函数如果调用成功的话,返回值为;如果调用失败返回值为。
下面我们以一个实例来说明如何使用函数建一个,具体代码如下所示:
...&ret&=&mkfifo(&&/tmp/cmd_pipe&,&S_IFIFO&|&0666&);&
if&(ret&==&0)&
...{&//&成功建立命名管道&}&
...{&//&创建命名管道失败&}
&&&&在这个例子中,利用目录中的文件建立了一个命名管道(即)。之后,就可以打开这个文件进行读写操作,并以此进行通信了。命名管道一旦打开,就可以利用典型的输入输出函数从中读取内容。举例来说,下面的代码段向我们展示了如何通过函数来从管道中读取内容:
pfp&=&fopen(&&/tmp/cmd_pipe&,&&r&&);&
...&ret&=&fgets(&buffer,&MAX_LINE,&pfp&);
&&&&我们还能向管道中写入内容,下面的代码段向我们展示了利用函数向管道写入的具体方法:
pfp&=&fopen(&&/tmp/cmd_pipe&,&&w+&);
...&ret&=&fprintf(&pfp,&&Here’s&a&test&string!/n&&);
2、读写有名管道
#include&&unistd.h&
ssize_t&read&(int&fd&,&void&*&buf&,&size_t&nbytes)
ssize_t&write&(int&fd&,&void&*&buf&,&size_t&nbytes)
在读写有名管道之前,需要用函数打开该有名管道,打开有名管道操作与其他文件有一定的区别:如果希望打开管道的写端,则需要另一个进程打开管道的读端,如果只打开有名管道的一端,则系统将暂时阻塞打开进程,直到有另一个进程打开管道的另一端,当前进程才会继续执行,因此,在使用有名管道时,一定要使用两个进程分别打开其读端和写端。
非亲缘关系进程使用有名管道通信应用实例:
向有名管道中发送数据的进程代码:&
从有名管道中接收数据的进程代码:
一、不得利用本站危害国家安全、泄露国家秘密,不得侵犯国家社会集体的和公民的合法权益,不得利用本站制作、复制和传播不法有害信息!
二、互相尊重,对自己的言论和行为负责。
本文标题:
本页链接:您所在位置: &
&nbsp&&nbsp&nbsp&&nbsp
管道通信之有名管道.doc7页
本文档一共被下载:
次 ,您可免费全文在线阅读后下载本文档
文档加载中...广告还剩秒
需要金币:100 &&
你可能关注的文档:
··········
··········
Linux进程间通信(三)---管道通信之有名管道及其基础实验
分类: Linux应用编程 15:44 1780人阅读 评论(4) 收藏 举报
有名管道accessmkfifo
有名管道(FIFO)
首先将上一节的有关有名管道的定义再贴出来
有名管道是对无名管道的一种改进,它具有以下特点:
它可以使互不相关的两个进程间实现彼此通信;
该管道可以通过路径名来指出,并且在文件系统中是可见的。在建立了管道之后,两个进程就可以把它当做普通文件一样进行读写操作,使用非常方便;
FIFO严格地遵循先进先出规则,对管道及FIFO的读总是从开始处返回数据,对它们的写则是把数据添加到末尾,它们不支持如 lseek()等文件定位操作。
有名管道的创建可以使用函数 mkfifo(),该函数类似与文件中的 open()操作,可以指定管道的路径和打开的模式。咱们还可以在命令行使用“mknod 管道名 p”来创建有名管道。
在管道创建成功后,就可以使用open()、write()和read()这些函数了。与普通文件的开发设置一样,对于为读而打开的管道可在open()中设置O_RDONLY,对于为写而打开的管道可在open()中设置O_WRONLY,在这里与普通文件不同的是阻塞问题。由于普通文件在读写时不会出现阻塞问题,而在管道的读写中却有阻塞的可能,这里的非阻塞标志可以在open()函数中设定为O_NONBLOCK。下面分别对阻塞打开和非阻塞打开的读写进行讨论。
对于读进程:
若该管道是阻塞打开,且当前FIFO内没有数据,则对读进程而言将一直阻塞到有数据写入。
若该管道是非阻塞打开,则不论FIFO内是否有数据,读进程都会立即执行读操作。即如果FIFO内没有数据,则读函数将立刻返回0。
对于写进程:
若该管道是阻塞
正在加载中,请稍后...您所在位置: &
&nbsp&&nbsp&nbsp&&nbsp
Linux系统管道和有名管道的通信机制.doc 17页
本文档一共被下载:
次 ,您可全文免费在线阅读后下载本文档。
下载提示
1.本站不保证该用户上传的文档完整性,不预览、不比对内容而直接下载产生的反悔问题本站不予受理。
2.该文档所得收入(下载+内容+预览三)归上传者、原创者。
3.登录后可充值,立即自动返金币,充值渠道很便利
需要金币:150 &&
Linux系统管道和有名管道的通信机制
你可能关注的文档:
··········
··········
Linux系统管道和有名管道的通信机制
摘自:???被阅读次数: 326
由?yangyi?于
18:27:59 提供
Linux 进程间通信的几种主要手段。其中管道和有名管道是最早的进程间通信机制之一,管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信。 认清管道和有名管道的读写规则是在程序中应用它们的关键,本文在详细讨论了管道和有名管道的通信机制的基础上,用实例对其读写规则进行了程序验证,这样做有利于增强读者对读写规则的感性认识,同时也提供了应用范例。1、 管道概述及相关API应用1.1 管道相关的关键概念管道是Linux支持的最初Unix IPC形式之一,具有以下特点:管道是半双工的,数据只能向一个方向流动;需要双方通信时,需要建立起两个管道;只能用于父子进程或者兄弟进程之间(具有亲缘关系的进程);单独构成一种独立的文件系统:管道对于管道两端的进程而言,就是一个文件,但它不是普通的文件,它不属于某种文件系统,而是自立门户,单独构成一种文件系统,并且只存在与内存中。数据的读出和写入:一个进程向管道中写的内容被管道另一端的进程读出。写入的内容每次都添加在管道缓冲区的末尾,并且每次都是从缓冲区的头部读出数据。1.2 管道的创建:#include int pipe(int fd[2])该函数创建的管道的两端处于一个进程中间,在实际应用中没有太大意义,因此,一个进程在由pipe()创建管道后,一般再fork一个子进程,然后通过管道实现父子进程间的通信(因此也不难推出,只要两个进程中存在亲缘关系,这里的亲缘关系指的是具有共同的祖先,都可以采用管道方式来进行通信)。1.3 管道的读写规则:管道两端可分别用描述字fd[0]以及fd[1]来描述,需要注意的是,管道的两端是固定了任务的。即一端只能用于读,由描述字fd[0]表示,称其为管道读端;另一端则只能用于写,由描述字fd[1]来表示,称其为管道写端。如果试图从管道写端读取数据,或者向管道读端写入数据都将导致错误发生。一般文件的I/O函数都可以用于管道,如close、read、write等等。从管道中读取数据:如果管道的写端不存在,则认为已经读到了数据的末尾,读函数返回的读出字节数为0;当管道的写端存在时,如果请求的字节数目大于PIPE_BUF,则返回管道中现有的数据字节数,如果请求的字节数目不大于PIPE_BUF,则返回管道中现有数据字节数(此时,管道中数据量小于请求的数据量);或者返回请求的字节数(此时,管道中数据量不小于请求的数据量)。注:(PIPE_BUF在include/Linux/limits.h中定义,不同的内核版本可能会有所不同。Posix.1要求PIPE_BUF至少为512字节,red hat 7.2中为4096)。关于管道的读规则验证:* readtest.c *#include #include #include main(){int pipe_fd[2];pid_char r_buf[100];char w_buf[4];char* p_int r_memset(r_buf,0,sizeof(r_buf));memset(w_buf,0,sizeof(r_buf));p_wbuf=w_if(pipe(pipe_fd)&0){printf(&pipe create error\n&);return -1;}if((pid=fork())==0){printf(&\n&);close(pipe_fd[1]);sleep(3);//确保父进程关闭写端r_num=read(pipe_fd[0],r_buf,100);printf( &read num is %d the data read from the pipe is %d\n&,r_num,atoi(r_buf));close(pipe_fd[0]);exit();}else if(pid&0){close(pipe_fd[0]);//readstrcpy(w_buf,&111&);if(write(pipe_fd[1],w_buf,4)!=-1)printf(&parent write over\n&);close(pipe_fd[1]);//writeprintf(&parent close fd[1] over\n&);sleep(10);} }程序输出结果:* parent write over* paren
正在加载中,请稍后...下次自动登录
现在的位置:
& 综合 & 正文
17、有名管道与无名管道之间的区别
1)无名管道管道是半双工的,数据只能向一个方向流动;需要双方通信时,需要建立起两个管道;只能用于父子进程或者兄弟进程之间(具有亲缘关系的进程)。
单独构成一种独立的文件系统:管道对于管道两端的进程而言,就是一个文件,但它不是普通的文件,它不属于某种文件系统,而是自立门户,单独构成一种文件系统,并且只存在与内存中。
数据的读出和写入:一个进程向管道中写的内容被管道另一端的进程读出。写入的内容每次都添加在管道缓冲区的末尾,并且每次都是从缓冲区的头部读出数据。(有点像队列哈)
#include &unistd.h&
int pipe(int fd[2])
该函数创建的管道的两端处于一个进程中间,在实际应用中没有太大意义,因此,一个进程在由 创建管道后,一般再一个子进程,然后通过管道实现父子进程间的通信(因此也不难推出,只要两个进程中存在亲缘关系,这里的亲缘关系指的是具有共同的祖先,都可以采用管道方式来进行通信)。
向管道中写入数据时将不保证写入的原子性,管道缓冲区一有空闲区域,写进程就会试图向管道写入数据。如果读进程不读走管道缓冲区中的数据,那么写操作将一直阻塞。
注:只有在管道的读端存在时,向管道中写入数据才有意义。否则,向管道中写入数据的进程将收到内核传来的信号,应用程序可以处理该信号,也可以忽略(默认动作则是应用程序终止)。
2)有名管道:不同于管道之处在于它提供一个路径名与之关联,以的文件形式存在于文件系统中。这样,即使与的创建进程不存在亲缘关系的进程,只要可以访问该路径,就能够彼此通过相互通信(能够访问该路径的进程以及的创建进程之间),因此,通过不相关的进程也能交换数据。值得注意的是,严格遵循先进先出(),对管道及的读总是从开始处返回数据,对它们的写则把数据添加到末尾。它们不支持诸如等文件定位操作。
有名管道的创建
#include &sys/types.h&
#include &sys/stat.h&
int mkfifo(const char * pathname, mode_t mode)
该函数的第一个参数是一个普通的路径名,也就是创建后的名字。第二个参数与打开普通文件的函数中的参数相同。如果的第一个参数是一个已经存在的路径名时,会返回错误,所以一般典型的调用代码首先会检查是否返回该错误,如果确实返回该错误,那么只要调用打开的函数就可以了。一般文件的函数都可以用于,如、、等等
3)无名管道由一个在基本文件系统存储设备上的,一个与其相连的内存,两个打开文件控制块(分别对应管道的信息发送端和信息接收端)及其所属进程的描述信息来标识,在系统执行()命令行之后生成。并在中返回管道的读通道打开文件描述等,在中返回管道的写通道打开文件描述符。从结构上看,无名管道没有文件路径名,不占用文件目录项,因此文件目录结构中的链表不适用于这种文件,它只是存在于打开文件结构中的一个临时文件,随其所依附的进程的生存而生存,当进程终止时,无名管道也随之消亡。
送入管道的信息一旦被读进程取用就从管道中消失了,读写操作之间符合先进先出的队列原则。
管道文件是进程间通信的工具,为了尽量少的占用系统存储资源,一般系统均将其限制为最大长度为()字节的小型文件。当欲写入的消息超过字节时,就产生了读、写进程之间的同步问题。首先写操作查找文件中当前指针的偏移量,然后从此位置开始尽量写入信息,当长度达到字节时,系统控制写进程进入睡眠状态,一直等待读进程取走全部信息时,文件长度指针置,写进程才被唤醒继续工作。
为防止多个进程同时读写一个管道文件而产生混乱,在管道文件的标志字项中设置了标志项,以设置软件锁的方式实现多进程间对管道文件的互斥使用。
无名管道存在着如下两个严重的缺点。
第一,无名管道只能用于连接具有共同祖先的进程。
第二,无名管道是依附进程而临时存在的。所以后来推出了一种无名管道的变种有名管道,它常被称为。有名管道除继承了无名管道的所有特性优点之外,还屏弃了无名管道的两个缺点。
首先,是一种永久性的机构,它具有普通的系统文件名。在系统下可利用命令建立永久的管道,除非刻意删除它,否则它将一直保持在系统中。
其次,正是由于有名管道以“文件名”来标识,所以只要事先约定某一特定文件名,那样所有知道该约定的服务进程,不论它们之间是否有亲属关系,都可以便利地利用管道进行通信。
通过下面的命令可以创建一个命名管道:
/etc/mknod pipe_name p
其中“”是要创建的命名管道的名字,参数必须出现在命名管道名字之后。
命名管道文件被创建后,一些进程就可以不断地将信息写入命名管道文件里,而另一些进程也可以不断地从命名管道文件中读取信息。对命名管道文件的读写操作是可以同时进行的。下面的例子显示命名管道的工作过程。
进程、、中运行的程序只是一条简单的命令,它们不断地把信息写入到命名管道文件中。与此同时,程序中的“”命令不断地从命名管道文件中读取这些信息,从而实现这些进程间的信息交换。
程序执行时,首先创建命名管道文件,此时程序处于等待状态,直到、、进程中某一个进程往命名管道中写入信息时,程序才继续往下执行。使用命令可以删除命名管道文件从而清除已设置的 命名管道。
下面是一个用于记录考勤的例子:
在主机上运行的程序产生命名管道,并不断地从命名管道中读取信息送屏幕上显示。
/tmp/text程序:
if [ ! p /tmp/pipe1 ]
/etc/mknode /tmp/pipe1 p
if [ “msg" = “
done & /tmp/pipe1
在终端上运行的是雇员签到程序。每个雇员在任何一台终端上键入自己的名字或代码,程序将把这个名字连同当时的签到时间送入命名管道。
/tmp/text1程序:
tty=‘‘$’’
today=‘’
echo “$$
done & /tmp/pipe1
当雇员从终端上输入自己的姓名后,运行程序的主机将显示类似下面的结果:
wang Thu Jan 28 09:29:26 BTJ 1999
he Thu Jan 28 09:29:26 BTJ 1999
cheng Thu Jan 28 09:30:26 BTJ 1999
zhang Thu Jan 28 09:31:26 BTJ 1999
named pipes(命名管道)管道具有很好的使用灵活性,表现在:
1) 既可用于本地,又可用于网络。
2) 可以通过它的名称而被引用。
3) 支持多客户机连接。
4) 支持双向通信。
5) 支持异步重叠操作。
不过,当前只有支持服务端的命名管道技术等不支持。 等数据库就有的连接方式。
(资料来源于互联网)
&&&&推荐文章:
【上篇】【下篇】}

我要回帖

更多关于 有名管道 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信