作为操作系统软件治理的核心 进程,那么进程间通信的方式就非常重要,常见的比如管道、消息队列、共享内存、信号量、信号、Socket等。本篇主要简单介绍下
我们知道每个进程都有自己独立的用户空间,而内核空间是共享的。
管道
ps -ef | grep mysql 其中的 | 就是一个管道符,只能进行单向传输数据。
mkfifo myPipe 创建一个管道
echo "hello" > myPipe 写入
cat < myPipe 读取
管道通信效率低,不适合进程间频繁的交换数据。
创建一个匿名管道,一个是管道的读取端描述符fd[0],另一个是管道的写入端描述符fd[1],只存在内存中。
管道就是内核里的一串缓存,写入的数据存储在内核中,另一个进程读取数据也是从内核中读取。只能在父子进程或者兄弟进程中使用。
消息队列
管道的通信方式效率比较低,管道不适合进程间频繁交换数据,消息队列可以解决这个问题。通过进程A写入消息队列后,B异步的进行读取。
但是消息队列本身是保存在内核中的消息链表中,主要有几点,消息的数据格式,消息序列化、反序列化等。
消息队列本身通信不及时,附件也有大小限制,并且不适合传输较大的文件,需要在内核态和用户态之间来回数据拷贝。这个比较耗费资源。而零拷贝本质就是为了减少这种开销。
共享内存
消息队列本身有内核态到用户态的开销,共享内存可以解决,不同的进程通过虚拟内存映射到不同的物理地址上,那么开通一块公共区域,进程时间可以通过直接访问,就可以减少这种开销,提升通信速度。
信号
我们知道 结束一个进程通过可以kill -9 pid,但是为什么就可以呢,其实就是通过信号给进程发送一个结束该进程的通知。
而ctrl+c sigint 终止进程 、ctrl+z 停止进程。
信号是进程间通信机制中唯一的异步通信机制
socket
以上介绍的其实只局限于本机进程通信,但是想要实现不同机器之间通信 可以使用socket套接字。主流的两种其实就是UDP和TCP。
这里简单说以下TCP的方式
1.客户端和服务端都进行创建socket
2.服务端调用bind,将绑定在IP和端口上
3.服务端调用listen,进行监听
4.服务端调用accept,等得客户端连接。
5.客户端调用connect 建立连接
6.客户端写入数据,服务端读取数据
7.断开连接,调用close,服务端读取到EOF,处理完毕后,服务端调用close,表示连接关闭。