进程间通讯方式
1. 管道(Pipe)(❌️)
这是最古老的Unix IPC方式,本质是内核中的一块缓冲区。
-
匿名管道(无名管道):只能在父子进程或兄弟进程之间使用(因为有亲缘关系)。数据单向流动(半双工),通常用于shell命令之间的连接(如
ps -ef | grep java)。 -
命名管道(FIFO):允许无亲缘关系的进程通信。它在文件系统中有一个可见的路径名,遵循先进先出原则。
2. 信号(Signal)(❌️)
这是异步通信方式,用于通知进程发生了某个事件(如Ctrl+C产生SIGINT)。它携带信息量极少(仅一个信号编号),主要用于进程控制(杀死进程、暂停、恢复),不适合传输数据。
3. 消息队列(Message Queue)
存放在内核中的消息链表。
-
优点:消息有类型和格式,接收方可以按类型读取,不需要像管道那样必须按字节流顺序读。
-
缺点:容量受系统限制,且内核需要频繁进行用户态和内核态的数据拷贝,效率不高。
4. 共享内存(Shared Memory)
这是速度最快的IPC方式。它允许多个进程将同一块物理内存映射到自己的虚拟地址空间,进程直接读写内存,无需内核介入拷贝。
-
致命缺点:多个进程同时修改同一块区域会引发数据错乱,因此必须配合同步机制(如信号量)使用。
5. 信号量(Semaphore)
严格来说,它不是传输数据的工具,而是一个计数器。它用于控制多个进程对共享资源(如共享内存)的互斥访问,解决进程同步与互斥问题。它常与共享内存搭配使用(PV操作)。
6. 套接字(Socket)
这是最通用的IPC,也是网络编程的基础。
-
不仅可以用于同一台机器上的进程通信(Unix Domain Socket,即本地套接字),更可以用于不同主机之间的进程通信(Internet Socket,即网络套接字)。
-
目前最主流的分布式系统通信方式(如HTTP、RPC、gRPC)底层都是Socket。
7. 文件(File)
多进程通过读写磁盘上的同一个普通文件来交换信息。虽然实现简单,但磁盘I/O速度极慢,且需要自己处理文件锁,主要用于少量配置数据的交换,不适用于高性能场景。
8. 内存映射文件(Memory-Mapped File)
是共享内存的一种特殊形式。它将磁盘文件映射到进程的虚拟地址空间,既享受了内存的访问速度,又能持久化存储。Java中的MappedByteBuffer就是典型实现。
总结
-
按速度排序(从快到慢):共享内存 > 内存映射文件 > 消息队列 > 管道 > Socket(网络) > 文件。
-
按是否需同步:共享内存和文件必须依赖锁或信号量;而消息队列和管道由内核维护,自带同步机制。
-
现代高并发场景:在实际的微服务或分布式系统中,Socket(网络通信) 使用最广;而在追求极致性能的中间件(如Redis、Nginx)中,共享内存 + 信号量 是标配。
浙公网安备 33010602011771号