系列文章目录
🌈座右铭🌈:人的一生这么长、你凭什么用短短的几年去衡量自己的一生!
💕个人主页:清灵白羽 漾情天殇_计算机底层原理,深度解析C++,自顶向下看Java-CSDN博客
❤️相关文章❤️:清灵白羽 漾情天殇-CSDN博客
系列文章目录
前言
一、PCB究竟是什么
1、概念
二、进程调度
1、上下文切换
1、保存当前进程状态:
2、加载新进程状态:
3、更新系统数据结构
1、进程表:
2、调度队列:
3、资源分配:
4、其它管理数据结构:
4、切换处理器控制权
2、分配处理器时间片
1、分配时间片:
2、进程执行:
3、时间片用尽:
4、调度下一个进程:
5、循环中执行:
3、执行进程
1、加载进程的代码和数据:
2、设置进程环境:
3、执行指令序列:
4、处理异常和中断:
5、交出处理器控制权
4、进程等待
1、等待资源:
2、进入阻塞状态:
3、资源变为可用:
4、重新调度进程:
5、进程完成
1、释放内存资源:
2、关闭文件描述符和其它资源:
3、释放其它系统资源:
4、更新进程状态:
5、发送信号:
6、资源回收:
总结
前言
这个系列我将为大家详细介绍有关操作系统进程和线程的概念,为后续JavaEE的学习打基础,这篇文章我通过进程的调度来为大家讲解有关进程的相关知识,只要能够理解进程是什么,那么对于线程(轻量级进程)的理解就不是什么难事了。
一、PCB究竟是什么
1、概念
概括的来说PCB是一个数据结构,用于存储和管理进程的信息,说的再直白一点他其实就是一个类或者说结构体,这个类里面定义了进程的各种属性和状态,在操作系统的内部,通常会使用一个队列来对这个PCB进行管理,这个队列通常使用数组或者哈希表来实现的,这一点学过数据结构的小伙伴应该都明白。
PCB当中包含了进程的唯一标识符,状态、程序计数器(CPU部件)CPU寄存器状态,堆栈指针,内存分配信息等,操作系统可以根据进程的唯一标识符来查找对应的PCB,以进行进程的管理和调度。
那么这个时候操作系统一旦根据PCB找到相应的进程,它会根据预先定义的调度算法来决定如何调度这个进程,调度算法决定了进程在CPU上执行的优先级和顺序。这些算法包括了先来先去服务、最短作业优先服务当然这些我们只需要简单了解即可。一旦操作系统选择了调度算法,操作系统就会根据该算法来决定下一个要执行的进程,这通常涉及到将进程从就绪队列当中取出,并且将其设置为运行状态,然后将控制权转移到该进程。那么进程调度之后又该如何呢?
(我在这里要多提一句,很多小伙伴始终不理解什么是进程,因为我们总是把进程的概念想的过于复杂了,其实进程就是一个正在运行的程序,那么什么是程序呢?就是数据+代码,进程是由操作系统内核部分当中的PCB以及堆栈当中的一系列代码组成的,那么内核是什么呢?很简单内核就是操作系统最核心的一部分代码,操作系统本身就是提前写进内存里面的一部分代码,我们可以发现一台电脑的内存当中有一个系统区域,厂家自带的这个其实就是操作系统占用的内存部分,而这个部分当中直接操作硬件的部分就叫做内核,PCB就是定义在这个里面的一个类,然后用数组或者哈希表实现的队列把这个类管理起来就叫做PCB调用队列。)
二、进程调度
1、上下文切换
如果当前正在执行的进程与将要调度的进程不同,操作系统将执行上下文切换,这包括当前进程的状态(寄存器值、程序计数器)并且加载新进程的状态,上下文切换是一个巨大的开销,因为它涉及到将处理器状态切换到新的进程上。接下来我来为大将详细介绍一下什么是上下文切换以及上下文切换的步骤。
1、保存当前进程状态:
当操作系统决定切换到另外一个进程的时候,首先需要保存当前进程的状态,这包括进程的寄存器值(例如通用寄存器、程序计数器)、进程控制块当中的其它重要信息(例如进程状态、优先级等)以及堆栈指针(进程存储在内存当中的代码,CPU执行的时候需要知道代码的确切位置,都需要到PCB查找)。当前的进程执行到了哪里,产生了哪些新的数据全部要被准确地记载道PCB当中,当该进程下一次被调度的时候会重新再释放出来。
2、加载新进程状态:
一旦当前的进程状态被保存好,操作系统就会加载下一个要执行的进程的状态,这包括加载新进程的寄存器值,程序计数器等以确保处理器能够继续执行新进程的指令。(因为进程包含了很多的代码,而代码经过汇编、编译之后会形成一条条的机器指令,这些机器指令自然也是进程的一部分,这些指令执行到了哪里,又要从哪一条指令开始执行PCB全部要记录)。
3、更新系统数据结构
在完成状态的保存和加载以后操作系统可能需要更新内核数据结构,以便正确跟踪进程的状态和系统资源的使用情况,这就涉及到了更新进程表、调度队列或者其它管理数据结构。更新数据结构主要涉及到以下几个方面:
1、进程表:
进程表是操作系统中用于跟踪每个活动进程信息的数据结构。在上下文切换之后,操作系统可能需要更新进程表中当前运行进程的状态,例如将其状态从“运行”改为“就绪”或“阻塞”,并更新相应的指针或索引。
2、调度队列:
调度队列是用于存储就绪进程的数据结构,以便操作系统可以根据特定的调度算法选择下一个要执行的进程。在上下文切换之后,操作系统可能需要更新调度队列,例如将当前运行进程移动到适当的位置,或将新的就绪进程插入到适当的位置。
3、资源分配:
这些表用于跟踪系统当中的各种资源,例如内存、CPU时间片、文件描述符等,在上下文切换之后,操作系统可能需要更新资源分配表,例如更新已分配资源的进程列表或者更新可用资源的状态。
4、其它管理数据结构:
操作系统可能还有其他数据结构,用于管理诸如文件系统、网络连接等其他方面的资源。在上下文切换之后,这些数据结构可能需要进行相应的更新,以反映进程状态的变化或资源的分配情况。
4、切换处理器控制权
最后处理器的控制权被转移到新加载的进程之上,其指令开始在处理器上执行,这标志着上下文切换完成,新进程开始执行。
2、分配处理器时间片
如果操作系统使用了时间片轮转调度算法,它将为新调度的进程分配一个时间片,即一段固定的时间,该进程可以使用处理器执行其任务。一旦时间片用尽,操作系统会暂停该进程并将处理器分配给下一个进程。
时间片轮转调度算法是一种常见的多道批处理系统中使用的调度算法,它基本为每个进程分配一个固定时间长度的时间片,让每一个进程轮流执行一段时间,当时间片用尽的时候,操作系统会暂停当前进程、并将处理器分配给下一个等待的进程。
1、分配时间片:
当一个进程被调度执行时,操作系统会为它分配一个时间片,通常是几毫秒或几十毫秒。这个时间片的长度通常是固定的,不过有些系统也会动态调整时间片的长度。
2、进程执行:
被选中执行的进程开始执行其任务,它会在处理器上运行自己的指令,直到时间片用尽或者自愿放弃处理器的控制权。
3、时间片用尽:
当进程执行了一个时间片的长度后,操作系统会暂停该进程的执行,并将其状态设置为就绪状态,以便后续再次被调度执行。
4、调度下一个进程:
一旦当前进程的时间片用尽,操作系统会选择下一个等待执行的进程,并将处理器的控制权转移到该进程上。通常情况下,操作系统会选择就绪队列中的下一个进程,或者按照某种调度策略来选择。
5、循环中执行:
这个过程会不断重复,直到所有进程完成执行或者系统停止。
3、执行进程
一旦进程获得了处理器的控制权,它开始执行其指令。这包括加载进程的代码和数据到内存中,并执行其指令序列。
1、加载进程的代码和数据:
首先、操作系统会将进程的代码和数据从存储设备例如硬盘当中加载到内存当中来,这包括将程序的可执行文件,例如可执行代码还有库文件等等加载到进程的地址空间、并且将进程所需要的数据从外部存储设备加载到内存的合适位置。
2、设置进程环境:
操作系统会为该进程设置执行环境,包括分配进程所需要的资源(如内存空间、文件描述符、CPU寄存器等等)这确保了进程能够在正确的环境当中执行。
3、执行指令序列:
一旦进程的代码和数据加载到内存当中,并且环境设置完毕(这里主要指分配内存空间、加载可执行文件、设置堆栈、初始化寄存器、设置文件描述符、设置权限和特权级别等),处理器会开始执行进程的指令序列,这些指令可以是任何合法的计算机指令,包括算数运算、条件分支、函数调用等,执行过程当中处理器会依次执行每一条指令、并且根据指令的操作码来执行相应的操作。
4、处理异常和中断:
在进程执行的过程当中可能会发生各种异常情况、比如访问非法内存除零错误等会哦这会有外部发生中断例如IO完成、始终中断等等、操作系统需要及时响应这些异常和中断,通常是通过处理中断处理程序、并且采取适当的措施例如终止进程、恢复执行等。
5、交出处理器控制权
当进程执行完毕之后或者遇到某些需要等待的情况时,它会交出处理器的控制权,以便其它进程可以执行,这可能是因为进程主动放弃CPU(例如进行IO操作),或者是因为操作系统通过调度算法决定切换到其它进程。
4、进程等待
如果进程需要等待某些资源(例如输入/输出完成、等待其他进程完成等),它可能会被放入阻塞状态,并释放处理器。当所需资源可用时,操作系统将重新调度该进程。进程等待是指当一个进程需要某些资源或事件发生时,它暂时无法继续执行,因此被置于阻塞状态。在进程等待期间,该进程会释放处理器(CPU),以便其他进程可以执行。一旦所需的资源变为可用,操作系统会重新调度该进程,使其继续执行。
1、等待资源:
进程可能因为多种原因需要等待资源,比如等待用户输入、等待磁盘IO完成、等待网络数据到达等。在这些情况下,进程需要在资源变为可用之前暂时停止执行。
2、进入阻塞状态:
当进程无法继续执行时,操作系统将该进程置于阻塞状态。在阻塞状态下,进程不会被调度执行,它会暂时释放处理器,并等待事件发生。
3、资源变为可用:
在某些情况下被等待的资源可能是其它进程所持有的,比如等待其它进程完成某些任务,当其他进程完成任务并且释放所需资源的时候,或者外部事件发生的时候,被等待的资源会变为可用。
4、重新调度进程:
一旦所需资源变为可用,操作系统会重新调度被阻塞的进程,使其继续执行,这通常包括将进程状态从阻塞状态转变为就绪状态,并且将其加入到就绪队列当中,以便在下一个调度的时候被选中执行。
5、继续执行:
一旦被重新调度、进程就可以继续执行其剩余的任务、它会重新获取处理器的控制权,并且根据需要执行相应的操作,如读取输入、处理IO操作等。
5、进程完成
当进程完成其任务或由于某种原因终止时,操作系统将释放该进程所占用的资源,并将其从进程队列中移除。
1、释放内存资源:
当进程完成的时候、操作系统会释放其所占用的内存资源、这包括将进程的代码、数据和堆栈等内存释放,并且将这些内存区域标记为可用,以便其它进程可以使用。
2、关闭文件描述符和其它资源:
进程可能会打开文件、网络连接等资源、当进程完成时操作系统会关闭这些资源、释放其占有的系统资源、这包括释放文件描述符、关闭网络连接、释放锁等操作。
3、释放其它系统资源:
除了内存和文件描述符外、进程可能还占用了其它系统资源、例如CPU时间、信号量、消息队列等,当进程完成的时候操作系统会释放这些资源,以便其它进程可以使用。
4、更新进程状态:
操作系统会将进程的状态设置为已经完成,并且从进程队列当中移除该进程,这样该进程就不会被再一次调度执行,也不会再占用系统资源了。
5、发送信号:
在某些情况下操作系统可能会发送信号通知其它进程或者用户进程已经完成,这可以通过操作系统的进程通信机制来实现,比如信号量、消息队列、管道等。
6、资源回收:
最后操作系统会回收进程所占用的所有资源,并且将其彻底清理和释放,这包括释放进程控制块、清楚进程相关的数据结构等等。
总结
进程的调度就为大家介绍到这里,有了对于操作系统的基本认识,后面我将会从代码的角度为大家介绍关于Java多线程编程的相关知识,能够帮助到各位就是对我最大的鼓励!