进程间通信方式有哪些?
管道
管道这种通讯方式有两种限制,一是半双工的通信,数据只能单向流动,二是只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。
管道可以分为两类:匿名管道和命名管道。匿名管道是单向的,只能在有亲缘关系的进程间通信;命名管道以磁盘文件的方式存在,可以实现本机任意两个进程通信。
信号
信号是一种比较复杂的通信方式,信号可以在任何时候发给某一进程,而无需知道该进程的状态。
Linux 系统中常用信号:
(1)SIGHUP:用户从终端注销,所有已启动进程都将收到该进程。系统缺省状 态下对该信号的处理是终止进程。
(2)SIGINT:程序终止信号。程序运行过程中,按 Ctrl+C 键将产生该信号。
(3)SIGQUIT:程序退出信号。程序运行过程中,按 Ctrl+\\键将产生该信 号。
(4)SIGBUS 和 SIGSEGV:进程访问非法地址。
(5)SIGFPE:运算中出现致命错误,如除零操作、数据溢出等。
(6)SIGKILL:用户终止进程执行信号。shell 下执行 kill -9 发送该信号。
(7)SIGTERM:结束进程信号。shell 下执行 kill 进程 pid 发送该信号。
(8)SIGALRM:定时器信号。 (9)SIGCLD:子进程退出信号。如果其父进程没有忽略该信号也没有处理该信 号,则子进程退出后将形成僵尸进程。
信号量
信号量是一个计数器,可以用来控制多个进程对共享资源的访 问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也 访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步 手段。
消息队列
消息队列是消息的链接表,包括 Posix 消息队列和 System V 消 息队列。有足够权限的进程可以向队列中添加消息,被赋予读权限的进程则可以读走队列中的消息。消息队列克服了信号承载信息量少,管道只能承载无格式字节流以及缓冲区大小受限等缺点。
共享内存
共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的 IPC 方 式,它是针对其他进程间通信方式运行效率低而专门设计的。它往往与其 他通信机制,如信号量,配合使用,来实现进程间的同步和通信。
Socket
与其他通信机制不同的是,它可用于不同机器间的进程通信。
优缺点
- 管道:速度慢,容量有限;
- Socket:任何进程间都能通讯,但速度慢;
- 消息队列:容量受到系统限制,且要注意第一次读的时候,要考虑上一次没有读完数据的问题;
- 信号量:不能传递复杂消息,只能用来同步;
- 共享内存区:能够很容易控制容量,速度快,但要保持同步,比如一个进程在写的时候,另一个进程要注
- 意读写的问题,相当于线程中的线程安全,当然,共享内存区同样可以用作线程间通讯,不过没这个必要,线程间本来就已经共享了同一进程内的一块内存。