博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Linux进程间通信--命名管道
阅读量:5327 次
发布时间:2019-06-14

本文共 1868 字,大约阅读时间需要 6 分钟。

IPC

前面总结了匿名管道,现在来看命名管道:由于匿名管道的一个限制就是:只能是有血缘关系的进程间才可以通信,比如:有两个同祖先的子进程,父子进程等;为了突破这一个限制,想让没有任何关系的两个进程间也能正常通信,所以就就有了命名管道这样的一个通信机制,一起来看看:

命名管道

一、原理:

       管道的一个不足之处是没有名字,因此,只能用于具有亲缘关系的进程间通信,在命名管道(named pipFIFO)提出后,该限制得到了克服。FIFO不同于管道之处在于它提供一个路径名与之关联,以FIFO的文件形式存储于文件系统中。命名管道是一个设备文件,因此,即使进程与创建FIFO的进程不存在亲缘关系,只要可以访问该路径,就能够通过FIFO相互通信。

值得注意的是,FIFO(first input first output)总是按照先进先出的原则工作,第一个被写入的数据将首先从管道中读出。

二、命名管道的创建与读写

       Linux下有两种方式创建命名管道。一是在Shell下交互地建立一个命名管道,二是在程序中使用系统函数建立命名管道。Shell方式下可使用mknodmkfifo命令,下面命令使用 mknod创建了一个命名管道:

mknod namedpipe

        创建命名管道的系统函数有两个:mknodmkfifo。两个函数均定义在头⽂文件sys/stat.h

        函数原型如下:

#include 
#include
int mknod(const char *path,mode_t mod,dev_t dev);int mkfifo(const char *path,mode_t mode);

        函数mknod参数中path为创建的命名管道的全路径名:mod为创建的命名管道的模式,指明其存取权限;dev为设备值,该值取决于文件创建的种类,它只在创建设备文件时才会用到。这两个函数调用成功都返回0,失败都返回-1

三、实例

用mkfifo创建命名管道:

其中_PATH_是文件路径名的宏定义:如下:

      “S_IFIFO|0666”指明创建一个命名管道且存取权限为0666,即创建者、与创建者同组的用户、其他用户对该命名管道的访问权限都是可读可写

      命名管道创建后就可以使用了,命名管道和管道的使用方法基本是相同的。只是使用命名管道时,必须用open()将其打开。因为命名管道是一个存在于硬盘上的文件,而管道是存在于内存中的特殊文件。

      需要注意的是,调用open()打开命名管道的进程可能会被阻塞。但如果同时用读写方式O_RDWR)打开,则一定不会导致阻塞;如果以只读方式(O_RDONLY)打开,则调用open()函数的进程将会被阻塞直到有写方打开管道;同样以写方式(O_WRONLY)打开也会阻塞直到有读方式打开管道。

四:结束

文件系统中的路径名是全局的,各进程都可以访问,因此可以用文件系统中的路径名来标识一个IPC通道。 命名管道也被称为FIFO文件,它是一种特殊类型的文件,它在文件系统中以文件名的形式存在,但是它的行为却和之前所讲的没有名字的管道(匿名管道)类似。

由于Linux中所有的事物都可被视为文件,所以对命名管道的使用也就变得与文件操作非常的统一,也使它的使用非常方便,同时我们也可以像平常的文件名一样在命令中使用。

五、命名管道的安全问题

   前面的例子两个进程之间的通信问题,也就是说,一个进程向FIFO文件写数据,而另一个进程则在FIFO文件中读取数据。试想这样一个问题,只使用一个FIFO文件,如果有多个进程同时向同一个FIFO文件写数据,而只有一个读FIFO进程在同一个FIFO文件中读取数据时,会发生怎么样的情况呢,会发生数据块的相互交错是很正常的?而且个人认为多个不同进程向一个FIFO读进程发送数据是很普通的情况。

   为了解决这一问题,就是让写操作的原子化。怎样才能使写操作原子化呢?答案很简单,系统规定:在一个以O_WRONLY(即阻塞方式)打开的FIFO中, 如果写入的数据长度小于等待PIPE_BUF,那么或者写入全部字节,或者一个字节都不写入。如果所有的写请求都是发往一个阻塞的FIFO的,并且每个写记请求的数据长度小于等于PIPE_BUF字节,系统就可以确保数据决不会交错在一起。

命名管道总结到此,其余通信机制,见下一篇博文。

赐教!

转载于:https://www.cnblogs.com/li-ning/p/9489954.html

你可能感兴趣的文章
js 页面定时刷新
查看>>
win7 jenkins 修改主目录
查看>>
Git学习笔记--日常基本使用
查看>>
nuget使用
查看>>
关于一类最小割图的建法
查看>>
Django---自定义admin组件思维导图
查看>>
输入一个链表,反转链表后,输出链表的所有元素。
查看>>
转如何用九条命令在一分钟内检查Linux服务器性能?
查看>>
win7下 go语言开发环境搭建(64bit)
查看>>
JavaScript权威指南--客户端存储
查看>>
leetcode Group Anagrams
查看>>
关于set和setsecure方法
查看>>
Django:(博客系统)使用使用mysql数据&创建post/category/tag实体,并同步到数据中...
查看>>
前端常用CSS小技巧
查看>>
LCT
查看>>
[POJ2406&POJ1961]用KMP解决字符串的循环问题两例
查看>>
传值调用与引用调用
查看>>
JZOJ 5922. sequence
查看>>
Object-C Xcode 编译提示 note: please rebuild precompiled header ZWYLPrefixHeader
查看>>
使用InternetGetConnectedState判断本地网络状态(C#举例)
查看>>