一、概述

在Linux系统中,以进程为单位来分配和管理资源。
由于保护的缘故,一个进程不能直接访问另一个进程的资源,也就是说,进程之间互相封闭。
在一个复杂的应用系统中,通常会使用多个相关的进程来共同完成一项任务,因此要求进程之间必须能够互相通信,从而来共享资源和信息。
所以,一个操作系统内核必须提供进程间的通信机制。

管道

管道和有名管道是最早的进程间通信机制之一,管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信。

管道是指用于连接一个读进程和一个写进程,以实现它们之间通信的共享方式,又称pipe文件。

管道是Linux支持的最初Unix IPC形式之一,具有以下特点:

管道是半双工的,数据只能向一个方向流动;需要双方通信时,需要建立起两个管道;

只能用于父子进程或者兄弟进程之间(具有亲缘关系的进程);

单独构成一种独立的文件系统:管道对于管道两端的进程而言,就是一个文件,但它不是普通的文件,它不属于某种文件系统,而是自立门户,单独构成一种文件系统,并且只存在与内存中。

数据的读出和写入:一个进程向管道中写的内容被管道另一端的进程读出。写入的内容每次都添加在管道缓冲区的末尾,并且每次都是从缓冲区的头部读出数据。

管道是所有Unix都提供的一种IPC机制

一个进程将数据写入管道,另一个进程从管道中读取数据

在shell中使用管道的例子

命令:“ls | more”

使用pipeline “|”将两个命令”ls”和“more”连接起来,使得ls的输出成为more的输入

也可以使用如下的两个命令

命令1:“ls > tmp”

命令2:”more < tmp”

命令1把ls的输出重定向到tmp文件中;

命令2把more的输入重定向到tmp文件

创建管道

管道的创建:
#include <unistd.h>
int pipe(int fd[2])
该函数创建的管道的两端处于一个进程中间,在实际应用中没有太大意义,因此,一个进程在由pipe()创建管道后,一般再fork一个子进程,然后通过管道实现父子进程间的通信。

注意:fd[0] 用于读取管道,fd[1] 用于写入管道。

管道读写

管道主要用于不同进程间通信。实际上,通常先创建一个管道,再通过fork函数创建一个子进程。

子进程写入和父进程读的命名管道:

管道的读写规则

管道两端可分别用描述字fd[0]以及fd[1]来描述。
需要注意的是,管道的两端是固定了任务的。即一端只能用于读,由描述字fd[0]表示,称其为管道读端;另一端则只能用于写,由描述字fd[1]来表示,称其为管道写端。
如果试图从管道写端读取数据,或者向管道读端写入数据都将导致错误发生。
一般文件的I/O函数都可以用于管道,如close、read、write等等。

系统文件 write(fd[1],buf,size)

功能:把buf中的长度为size字符的消息送入管道入口fd[1]
fd[1]—pipe入口
buf:存放消息的空间
size :要写入的字符长度

系统文件 read(fd[0],buf,size)

功能:从pipe出口fd[0]读出size字符的消息置入 buf中。
fd[0]――Pipe的出口

进程通信 管道 (pipe系统调用)

pipe(fd): 创建一个管道,fd[0]为管道的读端;fd[1]为管道的写端。 管道可用来实现父进程与其子孙进程之间的通信。管道以FIFO方式传送消息。

#include <stdio.h>
......
main()
{ int x,fd[2]; char buf[30],s[30]; pipe(fd); /*创建管道*/ while((x=fork()) = = -1); /*创建子进程失败时,循环*/ if(x = = 0) { sprintf(buf,“This is an example\n”); write(fd[1],buf,30); /*把buf中的字符写入管道*/ exit(0); } wait(); read(fd[0],s,30); /*父进程读管道中的字符*/ printf(“%s”,s);
}

有名管道

管道应用的一个重大限制是它没有名字,因此,只能用于具有亲缘关系的进程间通信,在有名管道(named pipe或FIFO)提出后,该限制得到了克服。

FIFO不同于管道之处在于它提供一个路径名与之关联,以FIFO的文件形式存在于文件系统中。这样,即使与FIFO的创建进程不存在亲缘关系的进程,只要可以访问该路径,就能够彼此通过FIFO相互通信(能够访问该路径的进程以及FIFO的创建进程之间)。

因此,通过FIFO不相关的进程也能交换数据。值得注意的是,FIFO严格遵循先进先出(first in first out),对管道及FIFO的读总是从开始处返回数据,对它们的写则把数据添加到末尾。

有名管道的创建

#include <sys/types.h>
#include <sys/stat.h>
int mkfifo(const char * pathname, mode_t mode)

该函数的第一个参数是一个普通的路径名,也就是创建后FIFO的名字。
第二个参数与打开普通文件的open()函数中的mode 参数相同。
如果mkfifo的第一个参数是一个已经存在的路径名时,会返回EEXIST错误,所以一般典型的调用代码首先会检查是否返回该错误,如果确实返回该错误,那么只要调用打开FIFO的函数就可以了。一般文件的I/O函数都可以用于FIFO,如close、read、write等等。

有名管道比管道多了一个打开操作:open。

FIFO的打开规则:

如果当前打开操作是为读而打开FIFO时,若已经有相应进程为写而打开该FIFO,则当前打开操作将成功返回;否则,可能阻塞直到有相应进程为写而打开该FIFO(当前打开操作设置了阻塞标志);或者,成功返回(当前打开操作没有设置阻塞标志)。

如果当前打开操作是为写而打开FIFO时,如果已经有相应进程为读而打开该FIFO,则当前打开操作将成功返回;否则,可能阻塞直到有相应进程为读而打开该FIFO(当前打开操作设置了阻塞标志);或者,返回ENXIO错误(当前打开操作没有设置阻塞标志)。

#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
main()
{ char buffer[80]; int fd; char *FIFO=“pipe1”; mkfifo(FIFO,0666); if(fork()>0){ char s[ ] = "hello!\n";fd = open (FIFO,O_WRONLY); write(fd,s,sizeof(s)); close(fd); } else{ fd= open(FIFO,O_RDONLY);read(fd,buffer,80); printf("%s",buffer); close(fd); }
}

管道的局限性

从IPC的角度看,管道提供了从一个进程向另一个进程传输数据的有效方法。但是,管道有一些固有的局限性:

1.因为读数据的同时也将数据从管道移去,因此,管道不能用来对多个接收者广播数据。
2.管道中的数据被当作字节流,因此无法识别信息的边界。

如果一个管道有多个读进程,那么写进程不能发送数据到指定的读进程。同样,如果有多个写进程,那么没有办法判断是它们中哪一个发送的数据。

转载于:https://www.cnblogs.com/yanghaishu/archive/2012/05/10/2495201.html

进程间通信(一)管道相关推荐

  1. linux内核剖析(八)进程间通信之-管道

    管道 管道是一种两个进程间进行单向通信的机制. 因为管道传递数据的单向性,管道又称为半双工管道. 管道的这一特点决定了器使用的局限性.管道是Linux支持的最初Unix IPC形式之一,具有以下特点: ...

  2. IPC 进程间通信方式——管道

    进程间通信概述 数据传输:一个进程需要将它的数据发送给另一个进程,发送的数据量在一个字节到几兆字节之间 共享数据:多个进程想要操作共享数据,一个进程对共享数据的修改,别的进程应该立刻看到. 通知时间: ...

  3. 进程间通信之管道(匿名管道与命名管道)

    进程间通信之管道 进程间通信 管道 什么是管道 管道分类--1.匿名管道 匿名管道举例 管道的特点 管道分类--2.命名管道 创建一个命名管道 举例 命名管道的打开规则 匿名管道与命名管道的区别 具体 ...

  4. Windows API 进程间通信,管道(Pipe)

    2019独角兽企业重金招聘Python工程师标准>>> 转载自:Windows API 进程间通信,管道(Pipe) 管道是一种用于在进程间共享数据的机制,其实质是一段共享内存.Wi ...

  5. 【Linux】进程间通信 —— 匿名管道 | 命名管道 | System V | 消息队列 | 共享内存

    进程间通信 0. 进程间通信 1. 管道 1.1 匿名管道 1.1.1 匿名管道原理 1.1.2 创建匿名管道pipe 1.1.3 基于匿名管道通信的4种情况5个特点 1.2 命名管道 1.2.1 创 ...

  6. linux信号管道,linux编程及应用任继平08 进程间通信-管道和信号.pptx

    linux编程及应用任继平08 进程间通信-管道和信号 管道示例 牛牛文库文档分享创建无名管道 牛牛文库文档分享文件描述符重定向 (1)cattest02test02 2>error test0 ...

  7. 进程间通信--命名管道

    几个术语 二义性:当我们往一个管道里面写端写数据的时候,比如写一个hello的时候,当我们写到he的时候,读端就已经开始读取数据了,所以这是不对的,这就是二义性 临界资源:多个流可以访问的一个共同的存 ...

  8. UNIX再学习 -- 进程间通信之管道

    一.进程间通信概念 首先,需要了解一下什么是进程间通信. 进程之间的相互通信的技术,称为进程间通信(InterProcess Communication,IPC). 下图列出 4 种实现所支持的不同形 ...

  9. 【Linux系统编程】进程间通信--有名管道

    命名管道的概述 无名管道,由于没有名字,只能用于亲缘关系的进程间通信(更多详情,请看<无名管道>).为了克服这个缺点,提出了命名管道(FIFO),也叫有名管道.FIFO 文件. 命名管道( ...

  10. 【Linux系统编程】进程间通信--无名管道(pipe)

    管道的概述 管道也叫无名管道,它是是 UNIX 系统 IPC(进程间通信) 的最古老形式,所有的 UNIX 系统都支持这种通信机制. 无名管道有如下特点: 1.半双工,数据在同一时刻只能在一个方向上流 ...

最新文章

  1. Eclipse-Java代码规范和质量检查插件-阿里编码规约
  2. 详解Node.js包的工程目录与NPM包管理器的使用_node.js
  3. python实训计算总秒数,Python:如何获取每个吉利秒数
  4. WIN8 打开图片内置管理员无法激活此应用
  5. 快速上手Ubuntu搭建Python编程环境
  6. SpringBoot maven打包源码发布到仓库配置
  7. SQLServer无法使用特殊主体'sa'的解决
  8. 图像的输入\输出和显示
  9. ATAC-seq原理及现有技术的比较
  10. 下一步怎么办?核心网带宽必须迅猛增长!
  11. ORACLE 10g创建单实例 ASM
  12. mfc配置GDI+有106个错误
  13. MySQL-快速入门(13)MySQL日志
  14. Http协议详解(深入理解)
  15. 软件测试员200题(练习)
  16. 初学视觉学习笔记----打开摄像头遇到的问题
  17. x58服务器主板装win7系统,技嘉Z390主板重装win7方法|Z390主板Bios设置及安装win7图文教程...
  18. Affinity Mattrix 亲和矩阵总结
  19. java liveness_Kubernetes Liveness and Readiness Probes
  20. 微信公众上传头像和分享

热门文章

  1. centos ffmpeg m3u8切片相关
  2. Gearman的使用
  3. TweenMax动画库学习(三)
  4. auto make System.map to C header file
  5. linux开机自动启动
  6. left join 和 left outer join 有什么区别
  7. 用友BQ商业智能设计模式——概述
  8. 2009年8月份答疑贴
  9. My interested stuff(2008-07-10)
  10. 【bzoj2300】【Luogu P2521】 [HAOI2011]防线修建 动态凸包,平衡树,Set