进程间通讯

进程间通讯的主体是进程,方式有信号、管道(有名管道、无名管道)、信号量、消息队列、共享存储(共享内存)、套接字。

管道:在内存上开辟一块空间,用文件描述符指向这段空间。

一、有名管道

有名管道:在文件系统的文件目录树上存在的一个文件标识,即文件名。但是管道文件不占据磁盘空间,需要传递的数据缓存在内存区域。
inode是存在磁盘上的,而且管道有大小。

一般的存储设备有寄存器(一个寄存器最多只能存4个字节)、缓存(数量不大,集成在CPU中,解决CPU和内存速度不匹配的问题)、内存、磁盘(空间大、速度慢)。
而管道文件将数据放在内存上,比起磁盘提高了效率。

这里写图片描述

A、B进程可以对同一块内存操作的原因是管道文件也是文件,只要A、B进程通过两个文件描述符指向这段内存,他们就可以这这段内存进行操作。

有名管道的操作:
创建:
命令:mkfifo
函数:int mkfifo(const char *filename,mode_t mode)
打开:int open(char *path,int flag,int mode);
读:int read(int fd,void *buff,size_t size);
写:int write(int fd,void *buff,size_t size);
关闭:int closes(int fd);

有关open、read、write、close等函数的使用请参见上一篇博客:
http://blog.csdn.net/qq_38623623/article/details/78378658

有名管道的特性:

1.open以只读方式打开一个管道文件,open会阻塞运行,直到有一个进程以只写或读写打开管道文件,open才会返回,进程才会接着执行。

2.open以只写方式打开一个管道文件,open会阻塞运行,直到有一个进程以只读或读写打开管道文件,open才会返回,进程才会接着执行。
若只有一个读不会open开辟内存空间,若只有一个写open也不会开辟空间,有读有写才会开辟空间。

3.read函数也会阻塞运行,直到写端写入数据或者所有的写端都关闭。
read读取数据并且会将内存上的已读数据清空。
read只要读到数据就会返回,假如等write写完再让read函数读取,会影响信息的实时性,所以这种思路不可取。

4.write的阻塞条件是当管道写满时。

二、无名管道

无名管道是没有名称的管道,无名管道没有文件存在。
依赖的理论基础是fork之后,父子进程对于文件描述符共享。

限制:只能应用于父子进程之间完成进程间通讯,并且管道的创建和打开必须在fork之前完成。

无名管道的操作:
创建和打开:
int pipe(int fds[2]);//函数声明写成数组也没关系,因为fds最后又退化为指针。

pipe函数的参数是一个由两个整数类型的文件描述符组成的数组的指针。
该函数在数组中填上两个新的文件描述符后返回0,如果失败返回-1。
两个返回的文件描述符以一种特殊的方式连接起来。数据基于先进先出的原则进行处理,这意味着如果你把字节1,2,3写到fd[1],从fds[0]读取到的数据也会是1,2,3.这与栈的处理方式不同,栈采用先进后出的原则。

pipe函数创建一个无名管道,然后用fds[0]指向读端,fds[1]指向写端。
因为管道是半双工通讯,所以在fork之后,父子进程分别关闭一段读写。
假如如果想使父进程写数据,子进程读数据,那么就关闭父进程的读fds[0]和子进程的写fds[1]。
读数据、写数据、关闭读写分别用read,write,close函数。因为是无名管道,所以不用打开文件。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值