进程间通信有哪些方式?

1.png

  • 管道可以被看作是不同进程之间的对话通道,其中一方发出声音(数据),而另一方接收。类似于声音传输的介质可以是空气或电缆,进程之间可以通过管道进行通信。在计算机中,管道是内核中的一段缓冲区,数据可以从管道的一端写入,存储在内核中,然后从另一端读取。

管道可以分为两类:匿名管道命名管道。匿名管道是单向的,只能在有亲缘关系的进程之间进行通信。而命名管道是双向的,允许本地的任意两个进程进行通信。

2.png

  • 信号:信号可以被看作是一种电报,发送方发送特定内容并指定接收进程,然后触发特定的软件中断。操作系统接收到中断请求后,找到接收进程并通知其处理信号。

例如,kill -9 1050表示向进程ID为1050的进程发送SIGKILL信号。在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消息队列。有足够权限的进程可以向队列中添加消息,具有读权限的进程可以读取队列中的消息。消息队列克服了信号传递信息量有限以及管道只能传递无格式字节流和受限缓冲区大小等问题。
  • 共享内存:共享内存的机制是将一块虚拟地址空间映射到相同的物理内存中。这样,一个进程写入的数据可以被其他进程立即读取。共享内存是最快的进程间通信方式,专门设计用于解决其他通信机制效率较低的问题。通常与其他通信机制(如信号量)配合使用,以实现进程间的同步和通信。

3.png

信号量:信号量可以类比为红绿灯,红灯停,绿灯行。实质上,信号量是一个整数计数器,用于控制多个进程对共享资源的访问。它常被用作一种锁机制,以防止一个进程正在访问共享资源时,其他进程也同时访问该资源。因此,信号量主要用作进程间以及同一进程内不同线程之间的同步机制。

信号量表示资源的数量,有两种原子操作用于控制信号量:

  • P操作:该操作会将信号量减1,如果减后信号量<0,则表示资源已被占用,进程需要被阻塞等待;如果减后信号量>=0,则表示仍有可用资源,进程可以继续执行。
  • V操作:该操作会将信号量加1,如果加后信号量<=0,则表示当前有被阻塞的进程,唤醒其中一个进程继续运行;如果加后信号量>0,则表示当前没有阻塞的进程。

P操作在进入共享资源之前使用,V操作在离开共享资源之后使用,这两个操作必须成对出现。

  • Socket:与其他通信机制不同,Socket用于不同机器间进程的通信。

优缺点:

  • 管道:简单;效率低,容量有限。
  • 消息队列:不及时,写入和读取需要用户态和内核态之间的拷贝。
  • 共享内存:能够轻松控制容量,速度快,但需要注意不同进程之间的同步问题。
  • 信号量:不能传递复杂的消息,一般用于实现进程间的同步。
  • 信号:作为进程间通信的唯一异步机制。
  • Socket:用于不同主机进程间的通信。

标签: java, Java面试题, 操作系统, Java问题合集, Java编程, Java问题精选, Java常见问题, 操作系统面试题