linux IPC 匿名管道

转自:http://blog.csdn.net/Xiejingfa/article/details/50819660

进程间通信,英文又称作IPC(InterProcess Communication)就是在不同的进程之间交换信息。我们知道,进程的用户是相空间互独立的,不能相互访问,所以为了使得进程间可以相互通信,操作系统需要提供一种介质使通信双方都可以访问。类似这样的介质有很多,比如磁盘上的文件,我们只要协调好进程访问文件的顺序,一个进程先“写”,一个进程后“读”,这样,两者就可以相互交换信息了。又比如我们经常使用的数据库,也可以作为信息交换的媒介。但是这些通信手段效率都太低了,需要在系统级别提供高效的进程间通信手段。今天我们就来介绍一种最古老的进程间通信方式 – 管道。

1、什么是管道?

如果你熟悉Linux系统,一定不会对管道感到陌生。在Linux系统中,我们经常通过符号“|”来使用管道,用以连接两个或多个命令。那管道是什么?实际上,管道是进程与进程间的数据流通道,它使得数据可以以一种“流”的形式在进程间流动。管道也是Unix/Linux系统中一种最常见的进程间通信方式,它在两个通信进程之间实现一个数据流的通道从而进行信息传递。管道通信具有以下特点:

1,管道是没有名字的,因此有称为匿名管道。它在系统中是没有实名的,不能在文件系统中看到管道。

2,在大多数系统中,管道通信是半双工的,也就是说数据只能在一个方向上流动。

3,管道中传送的是无格式的字节流。

4,管道的缓冲区是有限的,它的大小在include/linux/limits.h中由PIPE_BUF定义。

5,管道只能用于具有亲缘关系的进程间进行通信,如父子进程或者兄弟进程。

2、管道的创建

Linux下管道是通过pipe函数创建的,函数原型如下:

#include <unistd.h>

intpipe(intpipefd[2]);// 若成功则返回0,出错则返回-1

其中参数pipefd[2]是一个长度为2的文件描述符数组,pipefd[0]是读端,pipefd[1]是写端。

管道的关闭则使用close函数。

#include <unistd.h>

intclose(intfd);

管道关闭时,需要将pipefd[0]和pipefd[1]都关闭掉。

我们先用一段代码演示一下管道的创建:

pipe单进程实例

    在上面的例子中,我们使用pipe()函数创建了一个管道。到这里你可能会感到奇怪:不是说管道是进程间通信的方式吗?在单个进程中创建管道,然后从一段写入从另一端读出有什么意义?下面我们重点讲解一下管道如何实现进程间通信。

3、管道的读写

    正如你所想的,在单个进程中的创建管道几乎没有意义。前面我们说过管道只能用于父子进程或者兄弟进程间进行通信,通常我们先创建pipe,接着调用fork函数,从而创建从父子进程或者兄弟进程间的ipc通道。

    为什么这样就能创建进程通信的管道呢?其中的功臣就是fork函数。fork函数创建出来的子进程是父进程的一个拷贝,子进程从父进程中得到数据段和堆栈段的拷贝。这样,父子都拥有事先创建管道的文件描述符,都可以往管道中读写信息。一般用于文件的IO函数如read、write等都可以用于管道的读写。

管道数据流向

     经过fork函数调用之后,父子进程间存在两种数据流向的管道:一个是从父进程到子进程的数据通道,另一个是从子进程到父进程的数据通道。管道只支持半双工通信,所以我们必须关闭其中一个数据通道!!

    比如:如果你想建立一个父进程到子进程的数据通道,就要在父进程中关闭读端,在子进程中关闭写端。

    通常,利用pipe和fork的组合,我们可以构造父子进程或者兄弟进程间任意方向的的数据通道。

父子进程通过pipe通信

上面的例子演示了利用管道在父进程到子进程的通信,而管道在兄弟进程间通信则需要在父进程调用两次fork函数创建两个子进程,在两个兄弟子进程中维护通信管道。

4、管道读写的规则

管道写入的规则:程序向管道写入数据时,如果缓冲区有空闲空间,写进程立即向管道写入数据。如果缓冲区已满,那么写操作就一直阻塞到读进程读走数据为止。

管道读取的规则:如果请求的字节数大于PIPE_SIZE,则返回管道中现有的字节数。如果请求的字节数不大于PIPE_SIZE,则返回请求的字节数或现有数据的字节数(管道中的数据量小于请求的数据量)。

如果读写一端已经被关闭的管道是呢?

如果读一个写端已经被关闭的管道时,当所有的数据都被读取后,read返回0,表示文件结束。

如果写一个读端已经被关闭的管道,则产生SIGPIPE信号。如果忽略该信号或从处理程序中返回后,write函数返回-1,并且errno被设置为EPIPE。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,053评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,527评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,779评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,685评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,699评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,609评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,989评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,654评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,890评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,634评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,716评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,394评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,976评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,950评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,191评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,849评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,458评论 2 342

推荐阅读更多精彩内容