面试的时候遇见的,八股中的八股文, 进程间通信的方式, 觉得是个人都能说出来, 但是面试的时候面试官问, 这不重要, 你随便挑一个你平时是怎么使用的呢? 一下子不知道如何回答, 其实只是用过socket进行网络编程, 其他的背的挺明白但是好像没用过. 下来查询了一下发现平时其实都有用到过一点, 只是自己没注意!
- 系统IPC
- 管道pipe
- 匿名管道: 只能是具有亲缘关系的进程通信,
- 命名管道: 可以非亲缘关系的进程通信,
- 管道就是内核中的一串缓存
- 消息队列
- 就是保存在内核中的一个消息的链表
- 共享内存
- 内存中的一块虚拟地址空间, 映射到相同的物理内存中, 就像宿舍外面的厅, 你可以把公用的东西放到外面, 隔壁宿舍可以拿. 就不需要拷贝来拷贝去
- 信号量
- 其实就是一个计数器, 初始可以置1, 当进程取得权限的时候, 会执行P操作, 信号量减减, 进程放弃权限的时候, 执行V操作, 信号量加加.
- 信号
- 为了响应各种事件, 来发送信号
- 管道pipe
- socket
- 网络通信的套接字, 通过socket实现网络通信
此时大概进程间通信的大概就说完了, 以往的我以为记住这些就差不多了, 具体问什么再深入聊一下. 但是面试官要的是: 你最擅长使用哪种进程间通信方式呢? 介绍一下你平时是怎么使用的. 这个我就有点懵了.就说了说网络通信的时候我是怎么用socket的, 其他的完全想不起来. 下来查阅一下:
- 管道
管道只能单向通信, 一端写, 一端读.
无格式的字节流
创建匿名管道使用pipe
创建命名管道使用mkfifo(), 成功返回0.
在shell下使用的"|" 就是一个匿名管道, a | b的时候, a和b都是shell创建的子进程, 其父进程都是shell. - 消息队列
消息队列适合进程间频繁交换数据, 数据被分为一个个的消息体, 双方定义好数据类型.可以边发送边接收.
但是消息体有最大长度的限制,并且存在用户态和内核态的数据拷贝 - 共享内存
由于虚拟内存的存在, 每个进程都有自己的虚拟内存空间, 每一个进程拿出一块虚拟内存, 映射到相同的物理内存上, 这样不同进程写的东西别的进程立刻就能看到.但是肯定会出现写冲突. 因此可以使用信号量. - 信号量
使用共享内存的时候, 多个进程同时进行写操作, 需要一种保护机制.
P操作: 会将信号量减一, 如果此时信号量小于0则需要阻塞等待.
V操作: 会将信号量加一, 如果此时信号量小于等于0, 说明有阻塞的线程, 把其唤醒