什么是进程?
进程是一个独立的执行环境,包括自己的内存空间、程序计数器、文件句柄等。每个进程都是操作系统的一个独立实例,它们之间通常相互隔离。
通俗来说,进程就是程序的一次执行过程,程序是静态的,它作为系统中的一种资源是永远存在的。而进程是动态的,它是动态的产生,变化和消亡的,拥有其自己的生命周期。
用Linux 系统来举例 使用top命令 得到下图结果 每一个PID都是一个独立的进程
特点
进程之间相互独立,一个进程的崩溃通常不会影响其他进程。
进程通常比线程更重量级,创建和销毁进程的开销较大。
进程之间的通信通常需要使用特定的机制,如管道、套接字、共享内存等。
进程的组成
进程的特征
进程创建流程
1.分配进程控制块(PCB): 在创建进程之前,操作系统首先需要为新进程分配一个进程控制块(PCB)。PCB是一个数据结构,用于存储进程的相关信息,如进程状态、寄存器值、程序计数器(PC)、进程ID等。
2.为新进程分配资源: 操作系统需要为新进程分配必要的资源,包括内存空间、文件描述符、设备访问权限等。这些资源的分配需要考虑操作系统的策略和进程的需求。
3.加载程序: 一旦资源分配完成,操作系统会将要执行的程序加载到新进程的内存空间中。这通常涉及将程序的可执行文件从存储介质(如硬盘)读取到新进程的内存中。
4.初始化进程状态: 操作系统会为新进程设置初始状态,包括将程序计数器(PC)设置为程序的入口点,初始化堆栈和寄存器,为进程分配唯一的进程ID,设置进程状态为就绪(ready)等。
5.加入就绪队列: 新进程被初始化后,它通常被添加到就绪队列中,等待操作系统的调度。在就绪队列中,进程可以等待操作系统分配CPU时间以执行。
6.调度执行: 当操作系统决定运行新进程时,它将选择一个合适的进程,并将CPU控制权交给该进程。新进程开始执行其代码,从程序的入口点开始执行。
7.进程执行: 进程在执行期间可以执行其任务、访问资源、与其他进程进行通信等。操作系统会监控进程的状态,并在必要时进行调度。
8.进程终止: 进程执行完成后,或者由于某种原因终止,操作系统会释放进程占用的资源,更新进程状态为终止(terminated),并删除相应的进程控制块。
进程状态
类型
新建态(new):进程正在被创建时的状态
就绪态(ready):进程具备运行条件,等待系统分配 CPU 以便运行。
运行态(running):进程占有 CPU 正在运行。
阻塞态 / 等待态(wait):进程不具备运行条件,正在等待某个事件的完成。
终止态(exit):进程正在从系统中消失时的状态
进程状态切换
1.进程被创建之后操作系统会为进程初始化进程状态为新建态
2.操作系统等待程序加载完成之后会将进程状态切换为就绪态并假如就绪队列中等待CPU时间片的分配
3.当进程分配到CPU时间片之后会进入运行状态去执行
4. 操作系统通常为每个进程分配一定的时间片(也称为时间量子),用于在CPU上执行。当一个进程的时间片用完时,操作系统会将其状态从运行态切换回到就绪态,以便其他就绪进程有机会获得CPU时间执行。
5.当进程需要执行输入/输出(I/O)操作时,例如读取文件、等待网络数据到达或等待用户输入,它通常会进入阻塞态。在进行I/O操作期间,进程无法继续执行计算任务,因此操作系统将其状态切换为阻塞态,以便其他就绪进程可以获得CPU时间。
6.当进程等待超时或者被其他进程唤醒等原因会由阻塞状态到就绪状态重新等待CPU调度
7.当一个进程执行完毕会进入终止状态
进程的控制
什么是进程控制
进程控制(Process Control)是指操作系统通过管理和协调进程的创建、调度、同步、通信和终止等活动,以确保系统资源的有效利用和进程之间的有序协作。进程控制涉及到操作系统如何创建、暂停、终止、调度和同步多个进程,以及如何在进程之间进行通信。
原语
原语是一种特殊的程序,它的执行具有原子性。 也就是说,这段程序的运行必须一气呵成,不可中断。原语是操作系统内核里的一段程序
进程控制相关的原语
创建原语
撤销原语
阻塞原语和唤醒原语
切换原语
进程间通信(IPC)
什么是进程通信
进程通信 是指两个进程之间产生数据交互
进程通信的方式
共享存储
进程可以共享一块内存区域,允许它们直接读写共享的数据。这种通信方式非常高效,但需要谨慎处理同步和互斥,以避免数据竞争和一致性问题。
消息传递
直接通信方式
发送进程利用OS所提供的发送原语直接把消息发给目标进程
间接通信方式
发送和接收进程都通过共享实体(邮箱)的方式进行消息的发送和接收
管道通信
进程调度
什么是进程调度
进程调度(Process Scheduling)是操作系统的核心功能之一,它指的是操作系统决定哪个进程获得CPU时间并在CPU上执行的过程。进程调度的主要目的是合理地分配有限的CPU资源,以满足多个进程的需求,并确保公平性、性能和响应时间。
进程调度的重要性
资源利用率: 进程调度确保CPU资源得到充分利用。通过合理分配CPU时间,操作系统可以使多个程序并发运行,提高系统的吞吐量。
公平性: 进程调度确保不同程序之间的公平竞争。每个程序都有机会获得CPU时间,而不会长时间等待,从而提供了公平性。
响应时间: 进程调度可以确保对用户输入或请求的快速响应。对于需要快速互动的应用程序(如Web浏览器),低延迟和快速响应是至关重要的。
多任务处理: 现代计算中有多个任务需要同时运行,如多个应用程序、系统服务和后台任务。进程调度允许它们协同工作而不会相互干扰。
系统稳定性: 通过避免某个程序长时间占用CPU,进程调度有助于避免系统崩溃和资源枯竭。
进程调度的任务
1.选择下一个运行的进程: 当一个进程完成执行、被阻塞、或者其时间片用尽时,调度器需要决定下一个应该运行的进程。这个决策通常基于一些策略和算法。
2.分配CPU时间片: 进程调度还涉及到为每个进程分配合理的CPU时间片。不同的进程可能有不同的优先级,或者可能根据某种公平的分配策略获得CPU时间。
3.进程状态转换: 进程可能从就绪态切换到运行态,也可能从运行态切换到就绪态或阻塞态。进程调度要确保这些状态转换的合理性。
4.响应中断: 当发生硬件中断或其他事件时,进程调度需要响应中断,以便立即执行相应的中断服务程序。
5.控制和监视系统资源: 进程调度还涉及到监视系统资源的使用情况,以便根据需要重新分配资源。
进程调度算法
1.先来先服务 (First-Come, First-Served, FCFS): 这是最简单的调度算法,按照进程到达的顺序为它们分配CPU时间。它不考虑进程的执行时间,可能导致长作业等待时间过长。
2.最短作业优先 (Shortest Job First, SJF): SJF算法优先选择预计执行时间最短的进程。它可以最小化平均等待时间,但需要提前知道每个进程的执行时间。
3.最短剩余时间优先 (Shortest Remaining Time First, SRTF): 这是SJF的抢占式版本,允许更短的作业插队运行,以提高响应时间和减少等待时间。
4.时间片轮转 (Round Robin, RR): RR算法将每个进程分配一个时间片(固定时间量),并按顺序轮流执行它们。适用于多任务环境,但可能导致上下文切换开销较大。
5.多级反馈队列 (Multilevel Feedback Queue, MLFQ): MLFQ将进程按优先级分成多个队列,不同队列拥有不同的时间片大小。新进程从高优先级队列开始,根据其行为逐渐调整到不同的队列。这样可以适应不同进程的需求。
6.优先级调度 (Priority Scheduling): 进程被分配一个优先级,CPU总是分配给优先级最高的进程。可能导致优先级反转问题,需要额外的控制。
7.最高响应比优先 (Highest Response Ratio Next, HRRN): HRRN算法考虑等待时间和预计执行时间的比率,以决定下一个运行的进程。它旨在提高响应时间。
8.时间片可变的轮转 (Variable Round Robin, VRR): 类似于RR,但允许进程的时间片大小根据进程的需求动态调整。
9.公平共享 (Fair Share Scheduling): 公平共享算法旨在确保不同用户或组织的进程获得公平的CPU时间份额。
10.实时调度 (Real-time Scheduling): 用于实时系统,具有硬实时和软实时要求。这包括周期性任务和紧急任务的调度。
就绪队列
什么是就绪队列
就绪队列是操作系统用于管理已经准备好并等待被CPU执行的进程或线程的数据结构。这些进程或线程处于可运行状态,可以被调度执行。
就绪队列(Ready Queue)存储的是已经准备好并等待被CPU执行的进程或线程。这些进程或线程不是指IO任务,而是指已经具备了执行条件,可以立即参与CPU调度执行的进程或线程。
这些任务在就绪队列中等待CPU的调度,一旦CPU空闲,操作系统会根据调度算法从就绪队列中选择一个任务,使其开始执行。调度算法的选择对于系统性能和响应时间有重要影响。常见的调度算法包括先来先服务(FCFS)、最短作业优先(SJF)、时间片轮转(Round Robin)、优先级调度等。不同的调度算法有不同的优缺点,根据应用场景和需求选择适合的调度策略。
就绪队列中的内容
- CPU密集型任务:这些任务主要需要大量的CPU计算资源。它们通常执行一些复杂的计算操作,例如数值计算、图像处理、科学模拟等。
- 交互式任务:这些任务通常是用户交互式应用程序,如图形界面应用程序、文字处理器等。这些任务需要频繁地响应用户输入,并且需要及时的交互反馈。
- 批处理任务:批处理任务是一系列的作业或任务组成的批量作业。这些任务通常没有交互要求,而是按顺序执行,如后台的数据处理任务、报表生成等。
- 实时任务:实时任务是有时间限制的任务,需要在特定的时间内完成,以确保满足实时性要求。实时任务可能是硬实时(硬性截止时间)或软实时(软性截止时间)。
阻塞队列
什么是阻塞队列
阻塞队列(也称为等待队列或IO队列)是操作系统用于管理正在等待某个事件发生的进程或线程的数据结构,例如等待IO操作完成。当进程或线程发起一个IO操作时,它会从就绪队列转移到阻塞队列,并且在IO操作完成之前不会参与CPU调度。
阻塞队列是进程/线程等待IO操作完成的地方,也称为IO队列。一旦IO操作完成,进程/线程将被移回就绪队列,可以再次参与CPU调度。
需要注意的是,IO队列的具体内容取决于操作系统的实现和IO管理策略。不同的操作系统和IO设备可能会采用不同的IO队列结构和管理方式,以满足系统性能和资源利用的需求。
阻塞队列中包含的内容
- IO请求:IO队列中主要存放等待执行IO操作的请求。这些请求可能是磁盘读写请求、网络通信请求、设备IO请求等。
- IO任务:IO任务是指需要进行IO操作的进程或线程。当进程或线程执行IO操作时,它会进入阻塞状态,等待IO操作完成。这些进程或线程通常会被放入IO队列中,以便在IO操作完成后进行处理。
- IO缓冲区:IO队列可能包含用于暂存IO数据的缓冲区。当IO操作完成后,数据将从IO设备传输到缓冲区,然后再由进程或线程进行读取或处理。
- IO调度信息:IO队列中可能包含IO调度相关的信息,用于决定如何调度IO任务。例如,IO队列可能维护每个IO任务的优先级,以便在需要时进行优先级调度。
进程调度流程
1.进程就绪队列和调度器初始化: 当操作系统启动时,就绪队列会初始化为空,并调度器准备好进行调度。
2.进程创建和就绪态: 当用户或系统创建一个新进程,该进程进入就绪态,表示它已准备好执行。
3.进程到达就绪队列: 进程到达就绪态后,被放入就绪队列中,等待CPU时间。
4.调度器选择下一个进程: 当一个进程耗尽其时间片、被阻塞或从运行态切换到就绪态时,调度器会从就绪队列中选择下一个应该运行的进程。这个选择通常依赖于调度算法,如时间片轮转(Round Robin)。
5.保存当前进程的上下文: 调度器保存当前运行进程的寄存器状态、程序计数器值以及其他关键信息到该进程的进程控制块(PCB)中。
6.加载下一个进程的上下文: 调度器从选定的下一个进程的PCB中加载其寄存器状态、程序计数器值等信息。
7.执行新进程: 调度器切换控制权给新进程,使其继续执行。
8.进程执行: 新进程开始执行,直到它耗尽其时间片、主动放弃CPU、发生I/O操作等。
9.IO阻塞情况: 如果进程执行I/O操作,例如从磁盘读取数据,它可能会变为阻塞状态,此时CPU处于空闲状态。
10进程状态改变: 当I/O操作完成,进程从阻塞态切换到就绪态,等待CPU分配。
11.重复步骤4至步骤10: 上述过程会不断重复,直到所有进程都执行完成或等待事件。
这个流程包括了CPU密集型和IO密集型任务的处理。对于IO密集型任务,当它们发出I/O请求并等待I/O操作完成时,CPU会选择另一个就绪态的进程执行,以充分利用CPU资源。这有助于提高系统性能和响应时间,确保IO密集型任务不会浪费大量的CPU时间。
总之,进程调度流程会考虑CPU密集型和IO密集型任务的需求,以提高资源利用率和系统性能。流程中的步骤会不断循环,以确保不同进程有机会执行并减少等待时间。
进程上下文切换
什么是上下文
上下文指的是操作系统维护的进程的状态和信息。它包括了当前进程的寄存器状态、程序计数器值、内存映像、打开文件的信息等。上下文描述了进程执行时所需的一切,以便操作系统可以在恢复进程时确保它继续执行。
为什么需要上下文切换
操作系统需要执行上下文切换的几种情况,包括:
多任务处理: 操作系统必须在多个进程之间共享CPU时间,以实现多任务处理。
中断处理: 当硬件中断(如时钟中断、I/O中断)发生时,操作系统需要保存当前进程的状态,以便立即响应中断事件。
进程阻塞和唤醒: 当一个进程被阻塞,例如等待I/O完成时,操作系统需要切换到另一个可执行的进程。
上下文切换的过程
1.保存当前进程的上下文: 操作系统将当前运行进程的寄存器状态、程序计数器值等信息保存在该进程的进程控制块(PCB)中。
2.选择下一个要运行的进程: 调度器从就绪队列中选择下一个要运行的进程。
3.恢复下一个进程的上下文: 操作系统从下一个进程的PCB中恢复寄存器状态、程序计数器值等信息。
4.更新内存映像和资源表: 操作系统更新内存映像和资源分配表,以便下一个进程能够正确地访问其代码和数据。
5.切换到新进程: 操作系统将控制权交给下一个进程,使其继续执行。
上下文切换的开销
上下文切换是有开销的,因为它需要操作系统执行一系列复杂的操作,包括保存和恢复进程的上下文、选择进程、更新资源等。上下文切换的开销取决于操作系统的实现和硬件性能。减小上下文切换开销是操作系统设计的一个挑战。
用户态
用户态是计算机系统中的一种执行上下文,其中运行用户应用程序的代码。在用户态下,应用程序只能访问其自己的内存空间和一些受限的资源。用户态的进程通常没有直接访问系统内核的权限,不能执行特权指令或访问系统资源,如设备驱动程序、物理内存等。这是为了保护系统的稳定性和安全性,防止应用程序不经意地或故意地破坏操作系统。
内核态
内核态是操作系统内核的执行上下文,其中运行操作系统内核的代码。在内核态下,操作系统内核具有最高的特权级别,可以执行特权指令、访问系统的所有资源、管理设备驱动程序、分配内存等。内核态下的代码具有更高的权限和更广泛的访问权限,以便执行系统级任务和提供服务给用户态的应用程序。
进程的CPU切换流程
1.当前进程的运行(用户态): 在某一时刻,操作系统正在执行一个进程(当前进程)的应用程序代码,处于用户态。
2.触发CPU切换: 当操作系统决定要切换到另一个进程时,它会触发CPU切换,通常因为当前进程的时间片用完、进程主动放弃CPU、硬件中断或异常等。
3.保存当前进程的用户态上下文: 在进行切换之前,操作系统需要保存当前进程的用户态上下文,包括通用寄存器、程序计数器(PC)、堆栈指针(SP)等。
4.内核态到用户态的切换(从用户态到内核态的切换点): 这是一个关键的状态转换。在内核态到用户态的切换点,操作系统会从用户态切换到内核态,这是因为在内核态中执行进程切换和保存当前进程的内核态上下文所必需的。
5.保存当前进程的内核态上下文: 在切换到内核态后,操作系统会保存当前进程的内核态上下文,包括内核态下的寄存器、系统调用返回地址等。
6.选择下一个进程: 调度程序选择下一个要运行的进程。这通常基于调度算法,例如时间片轮转、最短作业优先、优先级等。选择的进程可以来自就绪队列中的其他进程。
7.加载下一个进程的内核态上下文: 操作系统从下一个要运行的进程的内核态上下文(通常是进程控制块或内核栈)中加载已保存的内核态上下文信息。
8.执行内核态工作: 在新进程的内核态上下文中,操作系统进行一些必要的内核工作,如保存和加载寄存器状态、选择进程、更新进程控制块等。
9.内核态到用户态的切换(从内核态到用户态的切换点): 在内核态工作完成后,操作系统将控制权切换回用户态,使进程继续执行其应用程序代码。
10.加载下一个进程的用户态上下文: 操作系统从下一个要运行的进程的用户态上下文中加载已保存的用户态上下文信息,包括通用寄存器、程序计数器、堆栈指针等。
11.切换到新进程: 此时,操作系统将控制权切换给新进程,使其开始执行。
12.新进程的执行(用户态): 新进程开始执行并继续其应用程序代码的执行,从其上次停止的位置开始。
13.进程状态改变: 当进程完成执行、被阻塞或需要等待事件时,它可能从运行态切换到就绪态或阻塞态,根据操作系统的调度策略。
14.重复步骤1至步骤13: 上述过程会不断重复,以确保多个进程有机会执行,并实现多任务处理。