Linux进程通信IPC--管道Pipe/Named Pipe

原创 2016年08月30日 23:21:58

前言: Linux 进程通信系列文章是对工作中使用的技术进行描述总结,前两篇文章分别讲述了MessageQueue、SharedMemory的方式,同作为Linux 最初支持Unix IPC的方式之一,管道也是进程间通信常用的方式。

管道(Pipe)

管道Pipe是Linux进程间通信的常用方式之一,正如其名字,像一根管子一样把进程A的输出连接到另一个进程B的输入。管道是半双工的,数据只能向一个方向流动,如果需要双方通信时,则必须建立起两个管道。

这里写图片描述

管道实际上是存在于内存中的文件,对这个文件的操作要通过两个已经打开文件描述符file_descriptor(简称fd)进行,两个fd分别代表管道的两端:读端和写端。然而管道是一种特殊独立的文件,不属于某一种文件系统,有独立的文件系统和自己的数据结构。

管道根据适用范围分为:无名管道(Pipe)和命名管道(Named Pipe)。

  • 无名管道(Pipe)

无名管道只能用于父子进程或者兄弟进程之间(具有亲缘关系的进程)。在Linux系统中可以通过系统调用建立起一个单向的通信管道,这种关系只能由父进程来建立且是单向的,因此如果需要双向通信时就需要建立起两个管道。管道两端的进程均将该管道看做一个文件,一个进程向管道中写的内容被管道另一端的进程读出,管道传输遵循“先入先出”(FIFO)的规则,写入的内容每次都添加在管道缓冲区的末尾,并且每次都是从缓冲区的头部读出数据。

  • 命名管道(Named Pipe)

命名管道克服了无名管道只能用于亲缘关系进程之间的缺陷。命名管道是建立在实际的磁盘介质或文件系统上而不是只存在于内存中,有自己名字的文件,它提供一个路径名与之关联,任何进程可以在任何时间通过文件名或路径名与该文件建立联系。命名管道引入了一种新的文件类型—FIFO文件(遵循先进先出的原则),并以FIFO的文件形式存在于文件系统中。即使与FIFO的创建进程不存在亲缘关系的进程,只要可以访问该路径,就能够彼此通过FIFO相互通信,实现了通过FIFO不相关的进程也能够交换数据。命名管道一旦建立,之后它的读、写以及关闭操作都与普通管道完全相同。

管道API 函数

  • 无名管道Pipe
int pipe(int file_descriptor[2]);

系统调用后,两个返回的文件描述符fd[0]、fd[1]以一种特殊的方式连接起来。fd[1]用于写入数据,fd[0]用于读出数据,写到fd[1]的所有数据都可以fd[0]读出来,相关数据遵循先进先出的原则(简写FIFO)。

  • 命名管道Named Pipe
int mkfifo(const char *filename, mode_t mode);
int mknode(const char *filename, mode_t mode|S_IFIFO,(dev_t)0);

mkfifo/mknode会依参数filename建立特殊的FIFO文件,该文件必须不存在,参数mode为该文件的权限。建立的FIFO文件其他进程都可以用读写一般文件的方式存取。

管道使用举例

  • 无名管道Pipe
int main(void)
{
    int n;
    int fd[2];
    pid_t pid;
    char line[MAXLINE];

    if(pipe(fd)< 0){        //先建立管道得到一对文件描述符
        exit(0);
    }

    if((pid = fork()) < 0)  //父进程把文件描述符复制给子进程
        exit(1);
    else if(pid > 0){       //父进程写
        close(fd[0]);       //关闭读描述符
        write(fd[1], "\nhello world\n", 14);
    }
    else{                   //子进程读
        close(fd[1]);       //关闭写端
        n = read(fd[0], line, MAXLINE);
        write(STDOUT_FILENO, line, n);
    }

    exit(0);
}
  • 命名管道Named Pipe
int main()  
{  
    int res = mkfifo("/tmp/my_fifo", 0777);  //创建FIFO文件
    if (res == 0)  
    {  
        printf("FIFO created/n");  
    }  
     exit(EXIT_SUCCESS);  
}

FIFO文件创建后,即可进行读写操作。

版权声明:本文为博主原创和转载(已表明出处)文章,欢迎交流。

进程间通信---------有名管道(named pipe/FIFO)

1、有名管道相关概念 管道应用的一个重大限制是它没有名字,因此,只能用于具有亲缘关系的进程间通信,在有名管道(named pipe或FIFO)提出后,该限制得到了克服。FIFO不同于管道之处在于...
  • CSDN_logo
  • CSDN_logo
  • 2015年06月10日 14:18
  • 720

Linux进程间通信方式之管道(pipe)

每个进程各自有独立的用户地址空间,任何一个进程的全局变量在另一个进程中都看不到,但是所有进程都共享内核地址空间,所以进程之间要交换数据必须通过内核,在内核中开辟一块缓冲区,进程1把数据从用户空间拷到内...
  • yangwen123
  • yangwen123
  • 2013年11月04日 08:18
  • 5620

进程间通信(4) - 管道(pipe)

1. 前言   本篇文章的所有例子,基于RHEL6.5平台。本篇只介绍管道(匿名管道/普通管道),命名管道在后续文章中会介绍。 2.管道特性 管道是Linux支持的最初Unix IPC形式之一,具...
  • shltsh
  • shltsh
  • 2015年06月16日 23:24
  • 3463

进程间通信:管道(pipe)

管道的概述 管道也叫无名管道,它是是 UNIX 系统 IPC(进程间通信) 的最古老形式,所有的 UNIX 系统都支持这种通信机制。 无名管道有如下特点: 1、半双工...
  • lianghe_work
  • lianghe_work
  • 2015年08月16日 23:19
  • 4307

利用pipe实现兄弟进程之间的通信

利用pipe实现兄弟进程之间的通信进程A创建2个子进程B,C。然后B C执行的程序利用pipe来通信:ls的输出通过管道到达另一个进程用wc统计单词数,字节数,行数。 execve系统调用用于执行指定...
  • vonzhoufz
  • vonzhoufz
  • 2015年08月22日 19:54
  • 1966

【Linux】进程间通信-命名管道FIFO

命名管道概述 如果我们要在不相关的进程间交换数据,那么使用FIFO文件将会十分方便。 FIFO文件通常也称为命名管道(named pipe)。命名管道是一种特殊类型的文件,它在文件系统中以文件...
  • xiajun07061225
  • xiajun07061225
  • 2013年01月06日 15:41
  • 14852

进程间通信-管道(PIPE)和有名管道(FIFO)

前面我们学习了一下进程,我们知道多,进程间的地址空间相对独立。进程与进程间不能像线程间通过全局变量通信。 如果想进程间通信,就需要其他机制。          常用的进程间通信方式有这...
  • w616589292
  • w616589292
  • 2016年03月22日 18:52
  • 2193

linux程序设计——pipe调用在两进程之间通信(第十三章)

13.4    pipe调用 在看过高级的popen函数之后,再来看看底层的pipe函数.通过这个函数在两个程序之间传递数据不需要启动一个shell来解释请求的命令.它同时提供了对读写数据的更多控制....
  • yiranant
  • yiranant
  • 2015年07月10日 18:51
  • 1206

fork创建子进程利用pipe管道通信

转自:这里。每个进程各自有不同的用户地址空间,任 何一个进程的全局变量在另一个进程中都看不到,所以进程之间要交换数据必须通过内核,在内核中开辟一块缓冲区,进程1把数据从用户空间拷到内核缓冲区,进程2再...
  • beautysleeper
  • beautysleeper
  • 2016年09月19日 14:00
  • 2271

Python进程间通信之匿名管道

匿名管道管道是一个单向通道,有点类似共享内存缓存.管道有两端,包括输入端和输出端.对于一个进程的而言,它只能看到管道一端,即要么是输入端要么是输出端.os.pipe()返回2个文件描述符(r, w),...
  • csujiangyu
  • csujiangyu
  • 2015年04月09日 10:26
  • 2381
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Linux进程通信IPC--管道Pipe/Named Pipe
举报原因:
原因补充:

(最多只允许输入30个字)