Linux 进程间通信面试总结

目录

1. 通信类型

1.1 管道(PIPE)

1.2 命名管道(FIFO)

1.3 消息队列(message queue)

1.4 共享内存(shared memory)

1.5 信号(singnal)

1.6 信号量(semophore)

1.7 套接字(socket)

2. 各通信方式的比较和优缺点

3. 进程间通信方式的选择


1. 通信类型

1.1 管道(PIPE)

管道这种通讯方式有两种限制,一是半双工的通信,数据只能单向流动,二是只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。

特点:

  • 1. 半双工(即数据只能在一个方向上流动),具有固定的写端和读端
  • 2. 它只能用于具有亲缘关系的进程之间的(父子进程或兄弟进程之间)
  • 3. 万物皆文件,可以被看成是一种特殊的文件,可以使用普通的读些 write,read 等函数。但它不是普通文件,并不属于其他文件系统,只存于内存中。

原型:

1. #include <unistd.h>
2. int pipe(int fd[2]); //返回值,若成功返回 0,失败返回-1

当一个管道建立时,它会创建两个文件描述符:fd[0]为读而打开,fd[1]为写而
打开,如下图:

 要关闭管道只需将这两个文件描述符关闭即可。

补充:

单个进程中的管道几乎没有作用,调用 pipe 的进程接着调用 fork,这样就创建了父进程和子进程直接的 IPC 通道。

1.2 命名管道(FIFO)

除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信(命名管道也叫FIFO)。

特点:

  • 1. FIFO 可以在无关的进程之间交换数据,与无名管道不同。
  • 2. FIFO 有路径名与之相关联,它以一种特殊设备文件形式存在于文件系统中。

原型:

1. #include <sys/stat.h>
2. //返回值:成功返回 0,出错返回-1
3. int mkfifo (const char *pathname, mode_t mode ) ;

补充:

FIFO 的通信方式类似于在进程中使用文件来传输数据,只不过 FIFO 类型文件同时具有管道的特性。在数据读出时,FIFO 管道中同时清楚数据,而且“先进先出”。

1.3 消息队列(message queue)

消息队列是由消息组成的链表,存放在内核中并由消息队列标识符标识。

特点:

  • 1. 消息队列是面向记录的,其中的消息具有特定的格式以及特定的优先级。
  • 2. 消息队列独立于发送与接收进程,进程终于时,消息队列及其内容并不会被删除
  • 3. 消息队列可以实现消息的随即查询,消息不一定要以先进先出的次序读取,也可以按消息的类型读取。

1.4 共享内存(shared memory)

共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的 IPC 方式,它是针对其他进程间通信方式运行效率低而专门设计的。它往往与其他通信机制,如信号量,配合使用,来实现进程间的同步和通信。

特点:

  • 1. 共享内存是最快的一种 IPC(进程间通信),因为进程是直接对内存进行存取。
  • 2. 因为多个进程可以同时操作,所以需要进行同步。
  • 3. 信号量+共享内存通常结合在一起操作,信号量用来同步对共享内存的访问。

补充:

  • 1. 当用 shmget 函数创建一段共享内存时,必须指定其 size;而如果引用一个已经存在的共享内存,则将 size 指为 0.
  • 2. 当一段共享内存被创建时,它并不能被任何进程访问。必须使用 shmat 函数连接该共享内存到当前进程的地址空间,连接成功后把共享内存对象映射到调用的地址空间,随后可像本地空间一样访问。
  • 3. shmdt 函数是用来断开 shmat 建立的连接。注意,这并不是从系统中删除该共享内存,只是当前进程不能再访问该共享内存而已。
  • 4. shmctl 函数可以对共享内存执行多种操作,根据参数 cmd 执行相应的操作。常用的是 IPC_RMID(从系统中删除该共享内存)。

1.5 信号(singnal)

信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生。主要作为进程间以及同一进程不同线程之间的同步手段。通过给进程发送相应信号,该进程接收到此信号后运行信号处理函数或者作出默认或忽略回应。

1.6 信号量(semophore)

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

特点:

  • 1. 信号量用于进程间同步,若要在进程间传递数据需要结合共享内存
  • 2. 信号量基于擦做系统的 PV 操作,程序对信号量的操作都是原子操作。
  • 3. 每次信号量的 PV 操作不仅限于对信号量值加 1 或减 1,而且可以加减任意正整数。

1.7 套接字(socket)

socket 套接字也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同机器间的进程通信。

2. 各通信方式的比较和优缺点

管道:速度慢,容量有限,只有父子进程能通讯

FIFO:任何进程间都能通讯,但速度慢

消息队列:

  • 容量受到系统限制,且要注意第一次读的时候,要考虑上一次没有读完数据的问题。
  • 由系统调用函数来实现消息发送和接收之间的同步,从而使得用户在使用消息缓冲进行通信时不再需要考虑同步问题,使用方便。

共享内存:能够很容易控制容量,速度快,但是要保持同步,比如一个进程在写的时候,另一个进程要注意读的问题。

信号量:不能传递复杂消息,只能用来同步

3. 进程间通信方式的选择

PIPE 和 FIFO(有名管道) 用来实现进程间相互发送非常短小的、频率很高的消息,这两种方式通常适用于两个进程间的通信。


共享内存用来实现进程间共享的、非常庞大的、读写操作频率很高的数据;这种方法适用于多进程间的通信。


其他考虑用 socket 。主要应用在分布式开发中。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值