进程间通信

进程间的通讯方式有:管道、消息队列、信号量、共享内存


管道

管道是一种半双工的通信方式,数据只能单向流动;管道在内存中存取数据,磁盘上只保留管道的信息,故管道的大小恒为0


管道的实质是一个内核缓冲区,进程以先进先出的方式从缓冲区存取数据:管道一端的进程顺序地将进程数据写入缓冲区,另一端的进程则顺序地读取数据,该缓冲区可以看做一个循环队列,读和写的位置都是自动增加的,一个数据只能被读一次,读出以后在缓冲区都不复存在了。当缓冲区读空或者写满时,有一定的规则控制相应的读进程或写进程是否进入等待队列,当空的缓冲区有新数据写入或慢的缓冲区有数据读出时,就唤醒等待队列中的进程继续读写。





管道总是从头指针head写,从尾指针tail读。写/读完成后,指针移动到合适位置。当头指针走到缓冲区的末尾时,又从另一端开始写。

管道分为pipe(无名管道)和fifo(有名管道)两种,除了建立、打开、删除的方式不同外,这两种管道几乎是一样的他们都是通过内核缓冲区实现数据传输。


有名管道和无名管道的区别?


无名管道: 
1、只能在有亲缘关系的进程(多为父子进程)间进行数据通信; 
2、无名管道是基于进程存在的,只能在程序运行时被创建,每次使用都要创建管道。

有名管道: 
1、可以在互不相关的进程之间实现通信;命名管道的名字对应于一个磁盘索引节点,但没有数据块,只是拥有一个名字和相应的访问权限,任何进程都可以通过文件名将其打开和进行读写。

2、可以使用命令创建管道,通过管道所在的路径名定位到该管道,两个进程间通信的时候直接使用该管道,不用再创建。在文件系统中可以查看到该管道文件,但大小恒为0;

消息队列

 消息队列是消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。消息队列可以对每个消息指定特定的消息类型,接收的时候不需要按照队列次序,而且可以根据自定义条件接收特定类型的消息。

信号量

  信号量是一个计数器可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。


共享内存

  共享内存允许两个或多个进程共享一个给定的存储区,这一段存储区可以被两个或两个以上的进程映射至自身的地址空间中,一个进程写入共享内存的信息,可以被其他使用这个共享内存的进程,通过一个简单的内存读取操作读出,从而实现了进程间的通信。

 

  采用共享内存进行通信的一个主要好处是效率高,因为进程可以直接读写内存,而不需要任何数据的拷贝,对于像管道和消息队里等通信方式,则需要再内核和用户空间进行四次的数据拷贝,而共享内存则只拷贝两次:一次从输入文件到共享内存区,另一次从共享内存到输出文件。



  一般而言,进程之间在共享内存时,并不总是读写少量数据后就解除映射,有新的通信时在重新建立共享内存区域;而是保持共享区域,直到通信完毕为止,这样,数据内容一直保存在共享内存中,并没有写回文件。共享内存中的内容往往是在解除映射时才写回文件,因此,采用共享内存的通信方式效率非常高。


共享内存有两种实现方式:1、内存映射 2、共享内存机制

1、内存映射

  内存映射 memory map机制使进程之间通过映射同一个普通文件实现共享内存,通过mmap()系统调用实现。普通文件被映射到进程地址空间后,进程可像访问普通内存一样对文件进行访问,不必再调用read/write等文件操作函数。

2、UNIX System V共享内存机制 

  IPC的共享内存指的是把所有的共享数据放在共享内存区域(IPC shared memory region),任何想要访问该数据的进程都必须在本进程的地址空间新增一块内存区域,用来映射存放共享数据的物理内存页面。

 和前面的mmap系统调用通过映射一个普通文件实现共享内存不同,UNIX system V共享内存是通过映射特殊文件系统shm中的文件实现进程间的共享内存通信。







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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值