一、CPU 执行指令的流程
CPU在执行指令的流程是取指令,分析指令,执行指令.指令是一个为八位的东西,前面四位是操作码,后面四位是操作数.CPU会取后面四位去进行分析,找到对应的数据,根据指令对照表执行一些操作,这样反复的执行每一条指令,直到有一条指令为全0的时候,那么CPU认为这个程序执行完毕.
二、进程与 PCB(进程控制块)
在执行一个程序的时候,这个程序会创建一个进程.一个程序可以对应多个进程.进程是操作系统分配的基本单位.PCB(进程控制块),每个进程都会有一个PID,这个是进程的标识符,由操作系统分配的,同一时刻不会存在两个进程的PID重复.PCB是一个结构体,在这个结构体里面有很多属性.我了解了一些比较重要的属性.分别是:
内存指针:一个进程的内存空间里面,有的部分是指令,有的部分是数据,这个时候内存指针就能够告诉操作系统哪个是指令,哪个是数据.
文件描述符表:一个进程想要读写文件,需要先打开,打开的时候就会在PCB里面构建一个文件相关的结构体,放到PCB的文件描述符表中.文件描述符表包含了很多的结构体,每个结构体表示了具体的文件信息.
进程的状态:进程的状态有很多种,我简单的分为了就绪和阻塞.
进程的上下文:这个属性类似于黑神话悟空这种存档的游戏.对于计算机来说,寄存器就是上下文,CPU内部有很多寄存器,用于保存当前程序运行的一些中间状态.进程在CPU上执行的时候,寄存器的值会不断的变化,进程离开CPU的时候,把这一时刻CPU上这些寄存器的值全都拷贝出来保存在内存中,就相当于在存档游戏进行存档.直到下次进程在CPU上运行的时候,这个时候寄存器会在内存中把数据读取出来,然后拷贝在CPU上,接着上次的操作继续执行.就跟游戏读档一样.
进程的记账信息:这个属性是统计每个进程都在CPU上运行了多久,在优先级机制下,可能会有某个进程分配到CPU的资源会非常少,通过记账信息这个属性,就能够进行灵活调整,给这个进程多分配点资源.
三、进程的隔离性
每个进程都有自己独立出来的内存空间,这是进程的隔离性,操作系统给每个进程划分了独立的内存地址空间,每个进程只能访问自己的数据,不能访问别的进程的内容.
四、线程的引入
由于进程的创建,销毁导致操作系统的开销特别大,所以引入了线程这个概念.线程是CPU调度的基本单位,一个进程可以包含若干个线程.引入线程可以减少操作系统的开销,同时可以提升执行效率,但是如果线程太多了反而会导致执行效率变低.线程也称为轻量级进程,创建线程的开销会比进程低很多.每一个线程都是执行流,都可以放在CPU上调度.
多线程的编程中,可能同一份数据会有多个线程执行,这会产生冲突,导致程序出现Bug.某个线程执行的途中,可能会出现异常,如果正确的捕获并且处理,那么就还好,如果没有正确的捕获处理,那么就可能会导致其他的线程也出现问题.就会导致整个进程被中止.
五、进程和线程的区别
进程和线程的区别就是:
进程和进程之间有着内存隔离,不会相互影响.线程是轻量级进程,同一个进程中的线程,如果其中一个出现异常,没有正确的处理,就会导致其他的线程也出现问题,从而导致进程被中止.进程与进程之间不会相互共享资源,而线程与线程之间能够共享资源.进程是操作系统分配的基本单位,线程是操作系统调度的基本单位.
六、Java 中的线程与 interrupt 方法
在Java中,main方法都是主线程,如果创建一个新的线程,那么CPU执行的顺序是随机的,因为CPU执行的顺序非常复杂,所以我们认为执行顺序是随机的.在lambda这个方法创建线程的时候.创建一个循坏的线程进行测试,有一个boolean类型的全局变量,在main里面,如果输入0,这个全局的变量会被设置为false,那么新的线程中的循坏将被终止,如果这个变量是局部变量,那么就会编译报错,这是因为lambda的变量捕获的一个语法问题,局部变量在外部修改之后,lambda里面可能不会修改,就会导致变量不一致的问题.如果Thread.sleep(10000).每执行一次线程,就会等待100_00毫秒,如果使用上面的方法,那么就算全局变量被改为false,线程也会等10000毫秒之后才会停止.这个时候我们可以使用Java库里面提供的方法,获取到进程的状态就行修改,然后在执行另外一个方法,interrupt(),这个方法可以唤醒sleep(),使线程退出阻塞状态.
以上内容是我自己对于线程和进程的粗略理解