进程间的通信 & 线程间的通信
这篇主要来理一下, 进程间的通信方式 (主要为linux系统… c语言)
和 线程间的通信方式 ( java )
进程间的通信(推荐阅读 : https://www.cnblogs.com/zgq0/p/8780893.html )
线程间的通信(推荐阅读 : https://blog.csdn.net/jisuanji12306/article/details/86363390)
知识点总结
对于进程间的通信
- 管道:速度慢,容量有限,只有父子进程能通讯
- FIFO:任何进程间都能通讯,但速度慢
- 消息队列:容量受到系统限制,且要注意第一次读的时候,要考虑上一次没有读完数据的问题
- 信号量:不能传递复杂消息,只能用来同步
- 共享内存区:能够很容易控制容量,速度快,但要保持同步,比如一个进程在写的时候,另一个进程要注意读写的问题,相当于线程中的线程安全,当然,共享内存区同样可以用作线程间通讯,不过没这个必要,线程间本来就已经共享了同一进程内的一块内存
对于线程间的通信
各个地方说的好像又有点不太一样
- 同步方式… 使用synchronized关键字
- while轮询, 轮询一个volatile修饰的变量 , 或者线程安全的一个东西
- wait / notify机制 , 或者说JUC包下的 重入锁 / condition 配合使用
- 管道 : PipedInputStream , PipedOutputStream…
额外来点补充
对于JVM的线程, 和 linux上操作系统中的线程, 他们是如何对应的呢?
Linux 2.6上的HotSpot使用了NPTL机制,JVM线程跟内核轻量级进程有一一对应的关系。线程的调度完全交给了操作系统内核,当然jvm还保留一些策略足以影响到其内部的线程调度,举个例子,在linux下,只要一个Thread.run就会调用一个fork产生一个线程。
如何排查一个 CPU 繁忙的java线程?
- top -Hp pid 查看应用进程的子线程的占用情况(生产数据未保留,暂以测试为例)
- 找到cpu占用率高的java线程 , 记录它的pid
- 使用 bc 工具之类的, 把这个pid 转为16进制
- 使用jps 找到本机上运行的java应用程序
- 使用jstack 对怀疑的java应用进行栈信息输出, 找到 关于 nid = 这个16进制的 线程, 这个线程对应了linux中的那条进程
- 然后再具体的探查问题
比如 :
"Reference Handler" #2 daemon prio=10 os_prio=0 tid=0x00007ff0880a0800 nid=0x4ee7 in Object.wait() [0x00007ff08c45d000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) at java.lang.Object.wait(Object.java:502) at java.lang.ref.Reference.tryHandlePending(Reference.java:191) - locked <0x00000000eb3363c8> (a java.lang.ref.Reference$Lock) at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)
名字是 " reference handler" 是一个守护(daemon)线程 , 优先级为10 , 操作系统中的优先级为 0 , jvm 线程中的 tid 是… 对应了本地线程的 0x4ee7 ()