Linux进程间通讯(2):管道、共享内存

三、管道

        管道是一种半双工通信,即允许信号在两个方向上传输,但某一时刻只允许信号在一个信道上单向传输。管道是把一个程序的输出直接连接到另一个程序的输入,常说的管道多是指无名管道,无名管道只能用于父子的进程之间,这是它与有名管道的最大区别。

(1)、管道有固定大小:实际上,管道是一个固定大小的缓冲区

(2)、管道读取进程比文件读取进程快:当所有当前进程数据已被读取时,管道变空。当这种情况发生时,管道一个随后的read()调用将默认地被阻塞,等待某些数据被写入,而文件read()调用返回文件结束。
 注:从管道读数据是一次性操作,数据一旦被读,它就从管道中被抛弃,释放空间以便写更多的数据。

(3)、管道文件存储在磁盘,普通文件存储在内存里面。

1、有名管道:

在文件系统中存在一个文件标识(文件名),但是管道文件不占据磁盘的空间,需要传递的数据缓存在内存区域。

 

具体操作有:

创建:mkfifo 文件名

打开:int open(char &path,int flag,);

在仅仅一端打开时,open会阻塞。直到有读端、写端,open才会返回 

读:int read(int fd,void *buf,size_t size);

read阻塞有两种情况:一种是管道中没有数据,另一种是管道中有数据,但所有的写端关闭

写:int write(int fd,void *buf,size_t size);

wirte阻塞有两种情况:一种是管道缓存区满,另一种是管道中有空间,但所有的读端关闭

关闭:int close(int fd);

注:读和写的次数没有必然关系

 

2、无名管道

没有名称的管道(没有管道文件存在)。fork 之后,父子进程对于文件描述符共享

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

 具体操作:

创建和打开:int pipe(int fds[2]);           pipe 函数创建一个无名管道,fds[0]指向读端,fds[1]指向写端。

因为管道是半双工通讯,所以在fork之后,父子进程分别关闭一对读写;

读数据:read(int fds,void *buff,size_t size);       read返回值为0,则读端通讯完成

写数据:write(int fds,void* buff,size_t size);      若子进程不关闭写端,当父进程结束,read返回 ??

关闭文件:close(fds);

 

 

四、共享内存:是最快的一种 IPC

共享内存是最快IPC原因:
(1)、在通讯之前访问内核对象,需要用户态切换内核态,但真正发送数据时,直接通过指针操作空间,不需要用户态切换内核态

(2)、共享内存可以直接通过指针将数据写到共享内存区域,接收方直接通过指针操作共享内存区域的数据,相比于管道、消息队列,共享内存少了两次数据的拷贝

注:两个进程的虚拟地址空间相等或者不相等,对于共享内存而言,无影响。

虚拟地址需要通过进程页表,进行页面映射才能找到物理内内存空间

 

 

 

注:本篇博客内容部分取自https://blog.csdn.net/century_sunshine/article/details/79882445

共享内存共享的是物理内存空间

 

具体操作:

1.shmget函数:创建共享内存

int shmget(key_t key,size_t size,int shmflg);

失败返回-1 成功返回标识符shmid

2.shmat函数:第一次创建共享内存时,它不被任何访问,要想启动对该共享内存的访问,必须将其连接到一个进程的地址空间中,这项工作由shmat函数完成。

void *shmat(int shmid,const void * shm_addr,int shmflg);

失败返回-1  成功返回指向共享内存第一个字节的指针

3.将共享内存从当前进程中分离

int shmdt(void *shmatrt)

失败返回-1,成功为0。

4.删除内核对象、且立即删除

int shmctl(int shm_id,int command,struct shmid_ds*buf);

5、优点:我们可以看到使用共享内存进行进程间的通信真的是非常方便,而且函数的接口也简单,数据的共享还使进程间的数据不用传送,而是直接访问内存,也加快了程序的效率。同时,它也不像匿名管道那样要求通信的进程有一定的父子关系。

6、缺点:共享内存没有提供同步的机制,这使得我们在使用共享内存进行进程间通信时,往往要借助其他的手段来进行进程间的同步工作。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值