进程间通信

简介: 进程间通信

管道

匿名管道

将前一个命令的输出,作为后一个命令的输入

我们可以得知,对于匿名管道,它的通信范围是存在父子关系的进程。因为管道没有实体,也就是没有管道文件,只能通过 fork 来复制父进程 fd 文件描述符,来达到通信的目的。

命名管道

也被叫做 FIFO,因为数据是先进先出的传输方式。

在使用命名管道前,先需要通过 mkfifo 命令来创建,并且指定管道名字:

shell

复制代码

$ mkfifo myPipe

另外,对于命名管道,它可以在不相关的进程间也能相互通信。因为命令管道,提前创建了一个类型为管道的设备文件,在进程里只要使用这个设备文件,就可以相互通信。

管道这种通信方式效率低,不适合进程间频繁地交换数据。当然,它的好处,自然就是简单,同时也我们很容易得知管道里的数据已经被另一个进程读取了。 不管是匿名管道还是命名管道,进程写入的数据都是缓存在内核中,另一个进程读取数据时候自然也是从内核中获取,同时通信数据都遵循先进先出原则。

消息队列

  1. 消息队列是保存在内核中的消息链表
  2. 消息队列的通信模式:生产者将数据放入队列,及完成;消费者取出,完成。不像管道是无格式的字节流数据。如果进程从消息队列中读取了消息体,内核就会把这个消息体删除。
  3. 消息队列生命周期随内核,如果没有释放消息队列或者没有关闭操作系统,消息队列会一直存在,而前面提到的匿名管道的生命周期,是随进程的创建而建立,随进程的结束而销毁。
  4. 克服了管道通信的数据是无格式的字节流的问题
  5. 缺点:
  • 通信不及时
  • 附件也有大小限制
  • 存在用户态与内核态之间的数据拷贝开销

共享内存

共享内存的机制,就是拿出一块虚拟地址空间来,映射到相同的物理内存中。这样这个进程写入的东西,另外一个进程马上就能看到了

信号量

信号量其实是一个整型的计数器,主要用于实现进程间的互斥与同步,而不是用于缓存进程间通信的数据。

控制信号量的方式有两种原子操作。P 操作和 V 操作

信号初始化为 1,就代表着是互斥信号量,它可以保证共享内存在任何时刻只有一个进程在访问,这就很好的保护了共享内存。

信号初始化为 0,就代表着是同步信号量,它可以保证进程 A 应在进程 B 之前执行。

信号

信号跟信号量,两者用途完全不一样!

对于异常情况下的工作模式,就需要用「信号」的方式来通知进程。

比如

  • Ctrl+C 产生 SIGINT 信号,表示终止该进程;
  • Ctrl+Z 产生 SIGTSTP 信号,表示停止该进程,但还未结束;
  • kill -9 <PID>,杀死<PID>号进程 所以,信号事件的来源主要有硬件来源(如键盘 Cltr+C )和软件来源(如 kill 命令)。

信号是进程间通信机制中唯一的异步通信机制,因为可以在任何时候发送信号给某一进程。

Socket

跨网络与不同主机上的进程之间通信

线程间通信

同个进程下的线程之间都是共享进程的资源,只要是共享变量都可以做到线程间通信,比如全局变量。

所以对于线程间关注的不是通信方式,而是关注多线程竞争共享资源的问题,信号量也同样可以在线程间实现互斥与同步:

  • 互斥的方式,可保证任意时刻只有一个线程访问共享资源;
  • 同步的方式,可保证线程 A 应在线程 B 之前执行;


相关文章
|
6月前
|
存储 并行计算 算法
C++进程间通信之共享内存
C++进程间通信之共享内存
351 0
|
5天前
|
消息中间件 NoSQL Linux
进程间通信
进程间通信
27 0
|
6月前
|
API
IPC(进程间通信)(下)
IPC(进程间通信)(下)
23 0
|
6月前
|
存储 消息中间件 Linux
IPC(进程间通信)(上)
IPC(进程间通信)
36 0
|
10月前
|
Unix
进程间通信(一)
进程间通信
46 0
|
10月前
进程间通信(二)
进程间通信
59 0
|
11月前
|
消息中间件
进程间通信(非常实用)
进程间通信(非常实用)
|
开发者
进程间通信 | 学习笔记
快速学习进程间通信,介绍了进程间通信系统机制, 以及在实际应用过程中如何使用。
74 0