JAVA程序员需要了解的计算机底层知识(3)
JAVA程序员需要了解的计算机底层知识(3)
程序、进程、线程、纤程
进程和线程:
举个例子,QQ是一个程序,在我们双击它的时候,OS会把它读入内存中(分配一块内存空间),当然也可以启动多个QQ,每一个QQ都是一个进程,都会被分配一块独立的内存空间,CPU开始读取内存中进程的指令,从进程里面的main函数所在的线程开始读取,在main下面会有很多的子线程,CPU会按照一定方式读取这些子线程。
线程共享进程的内部空间,线程没有自己的独立空间。
所以总结:进程是OS分配资源的基本单元,线程是执行调度的基本单位。所谓分配资源就是指分配内存空间,线程调度执行。
另外,线程在linux中的实现:
就是一个普通的进程,只不过这个进程和其他进程共享资源(内存空间,全局数据等 …)
其他的系统都有各自的所谓的LWP的实现 Light Weight Process
高层面的理解: 一个进程中不同的执行路线。
内核线程:是OS启动后 内核自己启动的线程,只有内核能运行,比如计时,比如定期清理垃圾。
纤程:
纤程可以理解为是 线程 的 线程。
正常来说JVM中创建一个线程Thread,需要对应操作系统内核中的一个线程(重量级线程 内核中需要起一个线程和thread对应),需要先从用户态转向内核态,在内核中申请各种各样的资源,再从内核态转回用户态,线程才能够实现。 纤程就是在Thread(重量级线程)内部分成不同的分支(线程中的线程),纤程并不对应着内核的线程,而是在JVM的层级去调度它,纤程是运行在用户空间的,而thread是对应在内核空间的。
(在我理解就是线程池对应的任务 stack,但是其实并不是,java语言并不支持线程,但是可以引入Quaser库进行支持,但是并不成熟)
纤程vs线程池:很短的计算任务,并不需要和内核打交道,并发量高。
优势:
1.占用资源少,OS线程 1M ,fiber 4K,
2.切换简单
3.启动多个10W+
僵尸进程
PCB数据结构:
一个进程在linux内部有一个数据结构,这个数据结构是PCB (process control block), 每一个进程都跟着一个PCB,内核维护这个进程就是PCB数据结构,PCB里面有的记录自己和别人共享一块内存空间,有的记录着自己拥有独立的内存空间。
进程的创建过程:
在进程创建的过程中,会调用系统函数fork()函数,fork()函数会调用clone()函数克隆一个线程。 再之后调用exec()函数运行这个进程。 被clone()的进程叫父进程,新的进程叫子进程。
僵尸进程的原理:
首先子进程是不能释放自己的PCB的,子进程的PCB是由父进程来维护的,如果子进程死掉了,父进程没有释放子进程的PCB,依然维护着子线程的PCB,那么这个无效的子进程就被称之为 僵尸进程。
孤儿进程
孤儿进程就是父线程死掉了,但是子进程还在运行,这个时候子进程就被称为 孤儿进程。
孤儿进程会被操作系统分配一个固定的进程作为子进程的父进程,新的父进程会维护子进程的PBC。
进程(任务)的调度
进程的调度是由 内核进程调度器 来决定的:
该哪一个进程运行?何时开始?运行多长时间?
linux的调度策略是可以自己设定的。
多任务有两种方式:
1.非抢占式:除非进程主动让出cpu,否则将会一直运行。
2.抢占式:由进程调度器强制开始或者暂停(抢占)某一进程的执行
进程调度的基本概念
进程类型:
IO密集型,大部分时间用于等待IO。
CPU密集型 发部分时间用于门头计算。
进程优先级:
实时进程 > 普通进程 (0-99)
普通进程的nice值(-20-19)
时间分配:
linux采用按优先级的CPU时间比
其他系统多采用按照优先级的时间片
linux默认的调度策略
对于实时进程: 使用sched_fifo和sched_rr两种
对于普通进程: 使用cfs
其中等级最高的是fifo,这种进程除非他自己让出cpu,否者linux会一直执行它。
除非等级更高的fifo或rr抢占它。
rr是指和fifo同级别优先级的进程。
只有实时进程主动让出或者执行完毕,普通进程才有执行的机会。
实时进程JVM创建不了,需要C语言来创建
中断
中断可以理解为 是硬件和操作系统的通信机制。硬件通知内核,或者软件通知内核的一个信号。
执行过程:
键盘 -----中断控制器-------cpu--------执行程序-------OS----------中断处理程序(已经写好的一堆处理程序,有处理键盘的,有处理打印机的)-----------------先由OS内核处理(上半场)------------再由应用程序处理(下半场)
中断又分硬中断和软中断
硬中断:
就是中断程序中关于硬件的通知信号,这个信号会对应一张中断向量表,比如
1-键盘-处理程序
2-鼠标-处理程序
0x80-软件-处理程序
.....
软中断:
软中断是关于软件的中断,是一个16进制的 80hex 号 中断,
所有这个号的都是软件的,这个号对应的又有一堆的函数,read(),write() …
等200多个函数。
用户空间的程序要调用OS内核所提供的那些函数,必须通过软中断向OS
申请(从用户态带内核态)。
拓展一下网络编程IO
client如果要从server中读取一个数据read()的时候,阻塞 / 非阻塞 其实是指 用户空间read() 一定会调用内核的 read() ,在内核态read()的时候,用户空间的read()还能不能干活?能干活就是非阻塞IO,不能干活就是阻塞IO。
JAVA程序员需要了解的计算机底层知识(2)
如果我有理解不正确的地方,请留言指正。
戏如人生 手打。