Javaman需要掌握的计算机底层知识(三)[进程 线程 纤程]
Warning:
本系列基调:好读书,不求甚解!
术业有专攻,我们不去开发操作系统,也不使用汇编语言,没必要太深究原理.
了解计算机底层知识,是为了更好的理解JVM!
目录
进程 线程 纤程
大量任务需要执行时,我们就要用"分而治之"的思想去解决它,划分为多层/多个小任务执行,然后归纳合并起来.这时候就要用到多线程执行.
面试高频:进程和线程有什么区别?
<Linux内核设计与实现>
-
进程就是一个程序运行起来的状态,是OS分配资源(内存空间,全局数据等)的基本单位,
每个进程有独立的内存空间,进程中的各线程调度执行时共享该内存; -
线程是一个进程中的不同的执行路线,是OS执行调度(指令)的基本单位,共享内存空间.
就是一个普通进程(LWP),只不过和其他进程那个共享资源.
每个系统有自己的LWP(light weight process)的实现,一般情况下,JVM中的一个线程对应一个操作系统的LWP,有的系统在配置JVM参数后也可以一个LWP对应多个线程.
LWP是内核线程(Kernel Thread)的一个接口,一个LWP对应一个内核线程,内核线程应该权限比较高,可以调度内核态和用户态的内存等.
以QQ为例,
QQ.exe:程序,静态的文件
双击运行后的QQ:进程,OS把QQ程序从磁盘中读取加载到内存中,由OS分配内存空间
通过QQ聊天等
纤程(Fiber)
可以理解为用户空间的轻量线程,自己实现的任务调度,而不是通过OS实现.
一般情况下,JVM中的一个线程对应一个操作系统的LWP,所以线程是需要OS调度的,在内核态和用户态之间切换,比较重量级.
纤程是由软件(JVM)在用户空间维护的多个轻量级的"线程",OS不直接参与调度.
优势:占用资源少(纤程4k,每个线程大概1M),切换比较简单,可以启动很多个(10W+)
一般很短的计算任务,不需要和内核打交道,并发量很高时,适合用纤程
Java支持纤程吗?
2020-03-22目前支持内置纤程的语言:kotlin,Scala,Go,Python(lib支持)
Java的纤程还不成熟,通过类库(Quasar)支持,openJDK正在尝试内置支持-“loom”
进程的其他相关概念
每一个进程都有一个PCB,每一个线程也有一个PCB(可以共享)
程序中进程的创建:
init进程是1号进程,
所有的程序都是首先从1号进程fork出自己的父进程,然后再从这个父进程fork出自己的各个子线程
(道生一,一生二…)
僵尸进程 孤儿进程
僵尸进程的资源基本都释放了,就剩下PCB没有被父进程释放
进程(任务)调度
内核进程调度器决定:该哪个进程执行,什么时候开始,执行多久
每个进程有自己的专属调度方案
多任务调度分为两种策略
- 非抢占式(cooperative multitasking)
进程主动让出CPU(yielding),其他进程才能运行;有可能一个任务特别慢,其他任务啥也干不了,一般系统都不是这种方案. - 抢占式(preemptive multitasking)
由进程调度器强制开始或暂停(抢占)某一进程.现在的系统一般是抢占式
进程调度器的调度策略
- linux2.5 O(1)调度策略:遍历每个进程都执行相同的一段时间.看起来似乎一碗水端平,但是有的进程可能不需要这么多时间,不讲究轻重缓急.
- Linux2.6.23 CFS:Completely Fair Scheduler,按优先级分配时间比例;并且按需分配,根据实际情况随时调整
按需分配:记录每个进程的执行时间,如果一个线程一段时间内不咋执行(等待IO),就少给点时间,相当于OS欠了这个进程一些帐;当这个线程又需要计算了,OS发现欠他帐,就优先给它时间.
进程调度基本概念
Linux默认的调度策略
RR:Round Robin

中断
中断是硬件或者软件通知操作系统一个信号,请求kernel执行自己的紧急事件
比如键盘上敲击一个按键,操作系统要优先做出相应的动作;怎么让它优先呢?这几需要中断.
中断分为软中断(80中断)和硬中断;硬件通知内核的是硬中断,软件通知内核的是软中断
硬中断
软中断
中断向量表里面有个特殊的中断号80H
int0x80是C语言的函数(interrupt)
现在新的Intel CPU有sysenter原语,更先进一些
ax bx 等都是寄存器,中断这里就是用了这几个寄存器