进程通信

188 阅读2分钟

进程通信方式

每个进程的地址空间都是独立的,一般而言是不能互相访问的,但是内核空间是每个进程所共享的,所以进程之间的通信要通过内核空间。

  1. 管道通信:管道是用于连接一个读进程和一个写进程以实现它们之间通信的一个共享文件,它就是内核空间的一段缓存。
  • 匿名管道(Pipes):用于具有亲缘关系的父子进程间或者兄弟进程之间的通信,只支持半双工通信
  • 命名管道(Names Pipes):以磁盘文件的方式存在,可以实现本机任意两个进程通信,遵循 FIFO
  1. 消息队列:是保存在内核中的消息链表,由消息队列标识符标识,能在不同进程之间提供全双工通信,它的传输效率要比管道快很多。例如A给B发送消息,只需要把消息体放在消息队列中,然后B进程需要的时候再从消息队列中获取消息,B也可以给进程A发送消息。 缺点: 如果进程A发送的数据比较大,占据的内存比较多并且消息传输比较频繁的话,消息队列就不太适合了,因为进程A发送消息时,拷贝数据要花费很多的时间去读取内存。

  2. 共享内存:多个就是多个进程可以拿出一块虚拟地址空间来,然后映射到相同的物理地址空间,这样的话一个进程写入了消息,另外一个进程可以立马读取到数据。但是会有多个进程同时对共享内存数据进行修改的问题。

  3. 信号量:信号量可以多个进程竞争共享资源,导致数据出错的问题。它可以让同一时间只有一个进程可以访问共享资源。信号量其实是一个整形计数器,主要用于实现进程之间的互斥。初始值为1,有P V操作,P是-1,V是+1,当信号量少于0的时候,说明共享资源被访问着。

  4. 套接字:与其它通信机制不同的是,它可用于不同机器间的互相通信

使用 jps 定位进程 id,再用 jstack id 定位死锁,找到死锁的线程去查看源码,解决优化.查看两个线程状态,都在等待另外的锁。

JVM会直接显示出来发生死锁的线程。

破坏循环等待条件:比如在一个进程中已有了小编号的资源,那么它就可以申请大编号的资源,但是已有大编号的资源就不可以申请小编号的资源,从而不会形成循环等待的现象。