文章目录
- 前言
- 什么是进程
- 如何描述进程
- 进程的属性
- 1. 进程标识符
- 2. 内存指针
- 3. 文件描述符表
- 4. 进程的状态
- 5. 优先级
- 6. 上下文
- 7. 记账信息
- 内存分配
- 并行和并发
前言
作为程序员,理解计算机的组成以及计算机是怎样运行的是很重要的,因为只有了解计算机我们才能更好地通过代码来运用计算机的特性。今天我将为大家分享计算机的核心之一:进程。
什么是进程
进程是计算机系统中正在运行的程序的实例。在操作系统中,进程是一个独立的执行单位,它拥有自己的内存空间、程序代码和运行状态。一个进程可以包括一个或多个线程,每个线程执行不同的任务,但它们共享进程的资源和上下文。
每个应用程序运行于现代操作系统之上时,操作系统会提供一种抽象,好像系统上只有这个程序在运行,所有的硬件资源都被这个程序在使用。这种假象是通过抽象了一个进程的概念来完成的,进程可以说是计算机科学中最重要和最成功的概念之一。
进程是操作系统对一个正在运行的程序的一种抽象,换言之,可以把进程看做程序的一次运行过程;同时,在操作系统内部,进程又是操作系统进行资源分配的基本单位。
如何描述进程
在计算机中使用结构体(C语言的结构体)来描述进程的属性,而这个结构体也叫做进程控制块(PCB)。
进程控制块(Process Control Block,简称PCB)是一个数据结构,它包含了正在运行的进程或任务的状态信息,以及该进程或任务所需要的其他信息,例如进程ID、程序计数器、寄存器、内存管理信息等。PCB通常是由操作系统内核维护的,它充当着进程与操作系统之间的中介,帮助操作系统管理进程的运行和资源分配,保证多个进程间的并发执行和相互独立的运行。每个进程都有自己独立的PCB,内核在切换进程时,会保存当前进程的PCB,然后载入下一个进程的PCB,并把CPU的控制权切换到下一个进程中。
而在底层进程是由一个节点是PCB的线性表、搜索树等来组织的。
进程的属性
1. 进程标识符
进程标识符(Process Identifier,PID)是操作系统中用于唯一标识一个正在运行的进程的数字标识。每个进程在操作系统中都有一个独特的PID。
PID是一个非负整数,在大多数操作系统中是唯一的。当一个进程被创建时,操作系统会为它分配一个新的PID。该PID在进程整个生命周期中保持不变,直到进程终止。
进程标识符的作用是在操作系统中唯一标识一个进程,让操作系统能够管理和控制进程的运行。
2. 内存指针
在操作系统中,每个进程都有自己独立的虚拟地址空间,而内存指针则是用于访问和管理进程的内存的变量或数据结构。内存指针存储的是一个内存地址,可以用于读取或写入该地址上的数据。
这些内存指针的值在进程执行期间会不断改变,根据程序的控制流和内存管理的操作而变化。它们允许进程访问各个内存区域,如代码区、堆区、栈区和数据区,从而实现程序的执行和数据的存储与访问。
需要注意的是,进程的内存指针只能在其自身的虚拟地址空间中有效,其他进程无法直接访问或修改其他进程的内存指针。操作系统通过地址映射和访问控制机制,提供了进程间内存隔离和保护的功能,保证各个进程的内存空间相互独立和安全。
3. 文件描述符表
文件描述符表是操作系统中用于跟踪和管理进程打开的文件的数据结构。每个进程都有其独立的文件描述符表,其中记录了当前进程所打开的文件或其他I/O资源的相关信息。
文件描述符是一个整数,用于表示打开的文件或其他I/O资源。操作系统使用文件描述符来跟踪进程与打开文件之间的关联关系,以便进行I/O操作、数据传输以及资源管理。
具体的文件描述符表结构和实现方式可能因操作系统而异,但通常情况下,操作系统会为每个进程维护一个固定大小的数组来存储文件描述符。这个数组的索引即为文件描述符的值,可以通过索引来访问和操作对应的打开文件。
4. 进程的状态
在操作系统中,进程可以处于不同的状态,这些状态描述了进程当前的情况或运行阶段。常见的进程状态包括:
-
创建:当进程刚被创建时,它处于创建状态。在这个阶段,操作系统为进程分配了必要的资源,并设置了进程的初始状态。
-
就绪:当一个进程已经获得了执行所需的所有资源,并且等待操作系统分配CPU时间片时,它处于就绪状态。就绪状态的进程等待调度器的调度,以便在一个或多个可用的CPU上执行。
-
运行:进程在运行状态表示它当前正在执行指令。在一个时刻,只有一个进程能运行在一个CPU上,即被调度为当前运行的进程。进程可以在运行状态下花费一段时间,执行其指令。
-
阻塞:当进程在执行过程中遇到某些事件,例如等待输入/输出、等待资源的分配或等待一个信号等时,它会进入阻塞状态。在阻塞状态中,进程暂停执行,并等待满足特定条件后重新进入就绪状态。
-
终止:运行中的进程可能会在执行完成后或由于异常情况(如错误、终止信号等)而终止。进程在终止状态时,它的所有资源被释放,包括分配的内存和打开的文件等。
5. 优先级
进程的优先级是操作系统用于确定进程调度顺序的一种机制,它决定了进程在竞争有限资源(如CPU时间片)时被分配的优先级和顺序。不同的进程可以有不同的优先级,高优先级的进程会获得更多的CPU时间,以便更快地执行。
在大多数操作系统中,进程通常被赋予一个数值表示优先级,这个数值可以是一个范围内的整数,通常是较大值表示较高的优先级。例如,Windows系统中的优先级范围为0-31,Linux系统中的优先级范围为-20到+19。
进程优先级的高低可以影响进程的调度。调度程序将优先选择具有更高优先级的进程,并为其分配更多的CPU时间。这意味着高优先级的进程可能更频繁地得到执行,而低优先级的进程则会相对较少地获得执行机会。
通过调整进程优先级,可以对系统资源进行更有针对性的分配和调度,以满足不同进程的需求。例如,对于关键任务或实时应用程序,可以将其优先级设置得更高,以确保其及时得到CPU资源的分配。
需要注意的是,进程优先级仅是调度程序的参考指标,实际的调度还受到其他因素的影响,例如进程的状态、进程等待的资源等。此外,过度依赖进程优先级可能导致其他进程得到很少的执行时间,从而影响系统的公平性和平稳性,因此,在设置进程优先级时需要慎重考虑。
总结起来,进程的优先级是操作系统用于确定进程调度顺序的机制,高优先级的进程会获得更多的CPU时间。通过调整进程优先级,可以实现对系统资源的更灵活分配和调度。
6. 上下文
进程的上下文是指操作系统在调度和执行进程时,需要保存和恢复的进程相关的状态信息。这些状态信息包括进程的寄存器内容、程序计数器、堆栈指针以及其他与进程执行相关的数据。
在操作系统中,当一个进程被调度执行时,它会从先前的执行状态中恢复上下文,并继续执行。当操作系统决定切换到另一个进程时,它会保存当前进程的上下文,然后装载和恢复另一个进程的上下文,以确保进程在下次执行时能够继续从上次离开的地方开始执行。
进程的上下文通常包括以下几个重要的部分:
-
寄存器内容:包括通用寄存器、程序计数器(PC)、堆栈指针(SP)等。这些寄存器保存了进程在被中断或切换之前的执行状态,以便在恢复时能够准确地继续执行。
-
内存管理信息:包括页表、段表或其他与内存管理相关的数据结构。这些信息描述了进程的内存布局和权限,以及与进程关联的物理内存页或虚拟内存页的映射关系。
-
文件描述符表:记录了进程打开的文件和I/O资源的相关信息,包括文件描述符、文件状态标志、打开的文件列表等。保存文件描述符表可以确保进程在恢复时能够正确地管理已打开的文件。
-
进程状态:记录了进程的当前状态,如运行、就绪、阻塞等。保存进程状态可以确定进程在调度时的优先级和执行顺序。
保存和恢复进程的上下文是操作系统进行进程切换和调度的关键操作。当操作系统决定切换到另一个进程时,它会保存当前进程的上下文,将控制转移到另一个进程,并恢复其上下文。这样可以实现多任务并发执行,使多个进程能够共享系统资源并按照一定的调度策略进行执行。
7. 记账信息
在操作系统中,进程的记账信息是用于记录和追踪有关进程执行和资源使用的统计数据。这些信息可以用于性能分析、资源管理和系统监控等目的。
进程的记账信息通常包括以下方面:
-
进程执行时间:记录进程在CPU上的执行时间,包括总执行时间、用户模式执行时间和内核模式执行时间等。这些数据可以用于计算进程的CPU利用率,评估进程的执行效率。
-
进程等待时间:记录进程在就绪状态下等待CPU时间片的时间。这可以用于分析进程等待时间的分布、发现可能的资源瓶颈和优化调度算法。
-
进程调度次数:记录进程被调度执行的次数。这可以用于评估进程的执行优先级、调度算法的效果和进程的响应性能。
-
进程使用的系统资源:记录进程使用的各种系统资源,如内存使用量、打开的文件数、网络连接数等。这可以用于资源管理和限制,以防止进程过度使用或滥用系统资源。
-
进程错误和异常:记录进程遇到的错误、异常和中断情况。这可以用于故障诊断和错误处理,帮助分析和解决进程执行中的问题。
其中进程的状态、优先级、上下文、记账信息属于是进程调度的相关属性,也是属于进程的核心属性
内存分配
进程内存分配是指操作系统为进程分配内存空间的过程,使得进程可以存储和访问所需的数据和代码。进程内存分配包括两个方面:进程地址空间的划分和虚拟内存的管理。
- 进程地址空间的划分
进程地址空间是指进程可以访问的虚拟内存空间,通常被划分为以下几个部分:
- 代码段:存放程序代码。
- 数据段:存放已经初始化的全局变量和静态变量。
- BSS段:存放未初始化的全局变量和静态变量。
- 堆区:存放动态分配的内存,如通过malloc等函数分配的内存。
- 栈区:存放函数调用时的临时变量和返回地址等信息。
- 虚拟内存的管理
虚拟内存是指操作系统通过地址转换技术提供给进程的一种抽象内存,使得进程看到的内存空间与实际物理内存不一定对应。虚拟内存的管理主要涉及以下几个方面:
- 页面置换:当物理内存不足时,操作系统需要将一部分进程数据从物理内存中换出到硬盘上,以腾出物理内存空间供其他进程使用。这个过程叫做页面置换。
- 页面调度:页面调度是指系统对请求访问的虚拟页面进行管理的过程。当进程访问一个虚拟页面时,如果该页面尚未在物理内存中,则需要从硬盘中获取该页面并将其加载到物理内存中,此过程叫做页面调度。
- 页面大小:页面大小是指进程虚拟内存空间被划分成的一系列大小相等的块。常见的页面大小包括4KB、8KB等。
- 页表:页表是记录虚拟地址和物理地址对应关系的数据结构。当进程访问一个虚拟地址时,需要通过页表将虚拟地址转换为物理地址。
程序中所获取到的内存地址,并非是真实的物理内存地址,而是经过了一层抽象,虚拟出来的地址。
访问内存上的任意地址的数据,速度都极快,时间上都差不多。正是因为内存的这个特性,才出现了数组的下标访问。如果当前进程的代码出现了bug,会导致访问的内存越界了,可能会影响其他的进程
针对进程使用的内存空间,进行“隔离”引入了虚拟地址空间。代码里不再直接使用真实的物理地址了,而是使用虚拟的地址,由操作系统和专门的硬件设备(MMU)负责进行虚拟地址到物理地址的转换。
哪个进程出bug,哪个进程就会崩溃,不影响其他的进程。
并行和并发
什么是并行
并行是指同时执行多个任务或操作的能力。在计算机领域中,特别是在多核CPU或分布式系统中,可以利用并行来加快任务的执行速度和提高系统的计算能力。并行 微观上同一时刻,两个核心上的进程,就是同时执行的
在并行处理中,多个任务或操作被分配给不同的处理单元或计算资源同时执行。这些处理单元可以是独立的CPU核心、多核CPU中的不同核心、不同的计算机节点或服务器等。每个处理单元独立地执行任务,并且它们之间可以并行地进行计算和数据操作。
并行处理通常用于解决需要高性能和高计算能力的任务,例如科学计算、大规模数据处理、图像和视频处理等。通过将问题分解成更小的子问题,并将每个子问题分配给不同的处理单元进行并行处理,可以显著缩短任务的执行时间。
什么是并发
并发是指系统或程序在同一时间段内执行多个独立的任务或操作。在计算机领域中,并发是一种处理多个任务同时进行的机制,通过任务切换和调度来实现任务的交替执行。
并发的主要目标是提高系统的效率和资源利用率。通过同时处理多个任务,系统可以更充分地利用CPU、内存和其他资源,以便更好地响应用户需求并提高整体的吞吐量。
并发可以在单个处理单元上,如单核CPU或单个线程中实现,也可以在多个处理单元之间,如多核CPU、多线程或分布式系统中实现。具体实现并发的方式包括时间片轮转调度、线程切换、进程切换等。
并行和并发的区别
并发在宏观上是同时进行的,微观上是串行的
并行在宏观上是同时进行的,在微观上是在不同核心上同时进行的
- 含义:
- 并行(Parallel):指同时执行多个任务,每个任务在多个处理单元上同时进行,每个处理单元可以是一个独立的CPU核心或者是多核CPU中的一个核心。
- 并发(Concurrency):指同时处理多个任务,多个任务交替执行,通过时间分片或者任务调度来实现多个任务之间的切换。
- 执行方式:
- 并行:多个任务同时执行,每个任务在独立的处理单元上并行进行。
- 并发:多个任务交替执行,每个任务在同一个处理单元上轮流执行,利用时间片或者任务切换来实现任务的并发执行。
- 目的:
- 并行:通过同时执行多个任务,提高整体的计算能力和执行速度,加快任务的完成。
- 并发:通过任务的交替执行和调度,实现多个任务之间的公平共享资源,提高系统的效率和吞吐量。
- 实现方式:
- 并行:通过多核CPU、多CPU或者分布式计算等方式,将不同的任务分配给不同的处理单元并同时进行处理。
- 并发:通过任务调度、线程或进程切换来实现任务之间的交替执行。
- 上下文切换:
- 并行:由于每个任务在独立的处理单元上执行,不存在上下文切换的开销。
- 并发:由于任务之间需要切换执行,存在上下文切换的开销,包括保存和恢复任务的执行上下文信息。