1.关于进程
进程基本概念
进程(process)也叫任务(task)。
进程是操作系统对一个正在运行的程序的一种抽象。也就是说,可以把进程看作程序的一次运行过程。 (一个正在运行的程序——>进程。没有跑起来就不算是一个进程)。
在操作系统内部,进程又是操作系统进行资源分配的基本单位。——>每个进程都对应一些资源。
job和process的关系: job——>process是job的一种具体实现,但是job不一定全是process。
进程是一个重要的“软件资源”,由操作系统内核负责管理:描述+组织
PCB和进程
计算机内部要管理任何现实食物,都需要将其抽象成一组有关联的、互为一体的数据(在Java中,可以通过类/对象来描述这个特征)
每一个PCB对象,就代表着一个实实在在运行着的程序,也就是进程。
描述:
讲清楚都有哪些属性特征。
使用结构体(C语言的结构体——>操作系统基本上都是C/C++来写的)来描述进程属性
用来描述进程的结构体——>PCB(进程控制块)
PCB里有哪些描述了进程的特征:
pid进程的身份标识符(唯一的数字)
内存指针:指向了自己的内存是哪些
文件描述符表:硬盘上的文件等其他资源
内存指针和文件描述符表描述了进程持有哪些硬件资源。
由于CPU的资源不好分配。
现在大多数的CPU都是多核CPU,而日常生活工作中,存在多个进程但是CPU少。我们希望这些进程可以“同时运行”——>分时复用。
并行:微观上同一时刻,两个核心的进程就是同时执行的。
并发:微观上同一时刻,一个核心上只能运行一个进程,但是它能够对进程快速地进行切换(只要切换数独足够快,宏观上人感知不到,人看起来就感觉这些进程在同时运行,但是微观上并不是同时进行的)
并行和并发由内核负责处理(应用程序感知不到)往往也把并行和并发统称为并发。
组织:
通过一定的数据结构把多个这样的基本单位串起来。
通过双向链表来把多个PCB串到一起。
创建一个进程,本质上就是创建一个PCB这样的结构体对象,把它插入到链表中。
销毁一个进程,本质上就是把链表上的PCB节点删除掉。
任务管理器查看进程列表,本质上就是遍历这个PCB链表。
调度器
操作系统中有一个重要的模块:调度器。就负责让有限的CPU来调度执行许多的进程(让这些进程看起来在同时进行)
进程调度相关的属性:
进程的状态:
就绪状态:随叫随到。进程随时准备好上CPU执行。
运行状态:正在CPU上执行。
阻塞状态:短时间内无法响应,也无法到CPU上执行。
很多操作系统不会明确区分就绪状态和运行状态。
优先级:
先给谁排,后给谁排,给谁排多点,给谁排少点。(进程也是有优先级的,而不是一碗水端平的。
上下文:
本质上就是存档的内容。
操作系统在进行进程切换的时候,需要将进程执行的“中间状态”记录下来,保存好。‘存档’
下次这个进程再上CPU上运行的时候,就可以修复上次的状态然后继续向下执行。
进程的上下文就是CPU中各个寄存器的值。
寄存器是CPU内置的存储数据的模块,保存的就是程序运行过程中的中间结果。
保存上下文就是把这些CPU寄存器的值记录保存到内存中。
恢复上下文就是把内存中的这些寄存器值恢复回去。
记账信息
操作系统,统计每个进程在CPU上占用的时间和执行的指令数目,根据这个来决定下一阶段该如何调度。
内存管理
内存(物理上是内存条——>可以存很多数据)
内存——>随机访问(闪现)——>数组取下标操作是O(1)
2.认识线程
一个线程就是一个“执行流”,每个线程之间都可以按照顺序执行自己的代码。多个线程之间“同时”执行着多份代码。
PCB和进程
PCB是使用链表来组织的(这句话并不具体),实际情况并不是一个简单的链表,而是一系列以链表为核心的数据结构。
操作系统对于调度这种事情只认PCB(系统内核中看不到‘进程’‘线程’这样的概念)。
一个进程可以包含一个线程(一个PCB)或者是多个线程(多个PCB)。
同一时刻,操作系统上有很多的进程,内核里就管理着十几号,上百号的PCB。这些PCB轮番去系统上调度执行,操作系统并不关心这些PCB哪些是一个进程中的。
如果每个进程有多个线程,那么每个线程都是独立上CPU调度的(线程是系统调度执行的基本单位)。每个线程也都有着自己的执行逻辑(执行流)
线程和进程
线程和进程的关系:进程包含线程。(一个进程可以包含一个线程或者是多个线程,但不能没有)
线程比进程更轻量——>把申请资源/释放资源的操作省下了。
只有第一个线程启动的时候,开销是比较大的,后续的线程就比较省事。
同一个进程的多个线程之间共用了进程的同一份资源(内存和文件描述符表)
内存:在线程1中new的对象,在其他线程中都可以使用。
文件描述符表:线程1打开的文件,在其他线程中都可以直接使用。
Java语言的特点:跨平台。(一次编译到处运行)
不同版本的JVM支持的·。
不同的JVM内部都封装了。
不同系统的API都执行同样的规则。
进程和线程的区别:
进程是包含线程的,每个进程至少有一个线程存在,即主线程。
进程和进程之间不共享内存空间,同一进程的线程之间共享同一个内存空间。
进程是系统分配资源的最小单位,线程是系统调度的最小单位。
Java的线程和操作系统线程的关系
线程是操作系统中的概念,操作系统内核实现了线程这样的机制,并且对用户层提供了一些API供用户使用。
Java标准库中的Thread类可视为是对操作系统提供的API进行了进一步的抽象和封装。
补充内容:
一个核心上执行的是一个线程。操作系统在调度的时候不关心进程只关心线程。
一个线程也是通过一个PCB来描述的。
一个进程里面可能是对应一个PCB也可能是对应多个。
PCB里的状态,上下文,优先级,记账信息,都是每个线程有自己的,各自记录各自的,但是在同一个进程里的PCB之间的pid是一样的,内存指针和文件描述符表也是一样的。
“调度”已经和进程没什么关系了,进程专门负责资源分配。线程来接管和调度相关的一切内容。
增加线程的数量时,不是可以一直提高速度的(线程太多,核心数目有限,不少的开销反而浪费在线程的调度上了。