程序和进程
一.程序和进程
1.1程序
程序是一组按照特定顺序编写的指令的集合,它用于指导计算机执行某个特定任务或完成某种操作。程序可以通过编程语言来描述和实现,它定义了问题的解决方案,并告诉计算机如何执行这些解决方案。
程序的目的是通过一系列的指令来操作计算机的硬件和资源,以实现特定的功能。这些指令可以是算术运算、逻辑判断、循环控制、数据传输等等操作,它们被编写成代码的形式,能够被计算机识别和执行。
程序的开发过程通常包括以下几个阶段:
需求分析:确定程序要解决的问题或达到的目标,并明确用户的需求和期望。
设计:根据需求分析的结果,设计程序的整体架构和模块划分,确定算法和数据结构等。
编码:使用编程语言将设计好的算法和逻辑转化为计算机能够执行的指令。
调试:在编码完成后,通过测试和调试确保程序的正确性和稳定性,修复错误和问题。
部署和维护:将程序部署到目标环境中,用户可以开始使用程序。之后可能需要进行维护和升级,以适应新的需求和改进性能。
程序可以用于各种领域和应用,包括软件开发、数据分析、人工智能、网络通信、游戏开发等。它们形成了现代科技和计算机应用的基石,对社会生产和生活的方方面面都有着重要的影响。
程序由不同的字段组成,这些字段定义了程序的不同部分和属性。
常见的程序字段包括
代码段(Code Segment):也称为文本段,存储了程序的实际执行代码。代码段通常是只读的,包含了计算机执行的指令和函数。
数据段(Data Segment):也称为数据区,存储了程序运行时使用的全局变量和静态变量。
BSS 段:BSS(Block Started by Symbol)段存储了未初始化的全局变量和静态变量。这些变量在程序启动时会被自动初始化为默认值,比如0。
堆(Heap):堆是动态分配内存的一部分,用于存储程序运行时动态创建的对象或数据结构。堆的大小可以根据需要自由扩展和收缩。
栈(Stack):栈用于存储程序的局部变量、函数参数和函数调用的上下文信息。栈是一种先进后出(FILO)的数据结构,用于支持函数的调用和返回。
除了上述字段之外,程序还可能包含其他字段,例如符号表(Symbol Table)用于记录变量和函数的名称与地址的映射关系,以及异常处理表(Exception Handling Table)用于处理程序异常情况等。
程序的字段和组织方式可以根据不同的编程语言和编译器进行不同的实现和优化。但是无论如何,这些字段都是为了帮助程序员更好地管理和组织代码以及实现程序的逻辑和功能。
1.2进程
进程是计算机中正在运行的程序的实例。每个进程都有自己的执行空间和资源,包括内存、文件句柄、CPU 资源等。进程是计算机进行任务调度和资源管理的基本单位。
一个进程可以包含一个或多个线程,每个线程在进程的上下文中运行,共享进程的内存和资源。线程是一个程序内的独立执行路径,它执行程序的一部分,并通过共享内存来与其他线程进行通信。
进程有以下几个主要特性:
独立性:每个进程是独立运行的,它们有自己的地址空间和资源,相互之间不会干扰。
并发性:多个进程可以同时存在并运行,操作系统通过任务调度算法来分配 CPU 资源,使多个进程能够并发执行。
资源管理:操作系统为每个进程分配和管理各种资源,包括内存、文件句柄、运行时间片等。
通信与同步:进程之间可以通过共享内存、消息传递等方式进行通信和同步,实现数据的共享和协作。
进程的生命周期通常包括以下几个阶段:
创建:当程序启动时,操作系统创建一个新的进程用于执行该程序。
就绪:进程已创建但暂时不执行,等待分配 CPU 资源。
运行:进程被操作系统选择为当前可执行的进程,并在 CPU 上执行。
阻塞:进程由于等待某些事件(例如等待输入/输出完成)而暂时无法继续执行,将进入阻塞状态。
挂起:操作系统可能会暂停进程的执行,并将其从内存中移动到磁盘上以节省资源。
终止:进程执行完成或发生错误时结束,并释放占用的资源。
操作系统通过进程调度算法来决定在某个时间点运行哪个进程,以实现多任务的并发执行。进程的管理和调度由操作系统负责,包括创建、终止、切换、通信等。进程的概念是计算机操作系统和并发编程的重要基础。
1.3进程和程序的区别
![2023-09-19T08:46:32.png][1]
进程和程序是计算机中两个相关但不同的概念。
程序是一组按照特定顺序编写的指令集合,用于告诉计算机执行特定的任务。它是静态的,是代码的逻辑表示,通常保存在存储设备中,如硬盘或闪存。
进程是程序的执行实例,是计算机中正在运行的程序。它是动态的,具有独立的内存空间和资源。一个程序可以创建一个或者多个进程的实例。每个进程运行在自己的上下文中,具有自己的内存、寄存器、堆栈和文件句柄等资源。
因此,可以总结出程序和进程之间的区别如下:
定义:程序是静态的代码集合,而进程是程序在计算机上的运行实例。
动态性:程序是静态的,不执行任何操作。而进程是程序的执行状态,具有动态性。
资源和上下文:程序不占用计算机资源,而进程拥有独立的资源,如内存、文件句柄等,并且运行在自己的上下文中。
并发性:程序本身不能并发执行,但一个程序可以创建多个进程来实现并发执行。
生命周期:程序的生命周期从编写到存储,而进程的生命周期是在运行时创建、启动、执行、终止等过程。
综上所述,程序只是指定要执行的指令的代码集合,而进程是程序在计算机上运行时的实例,具有自己的资源和上下文。程序通过创建进程来实现在计算机上的实际执行。
1.4Linux中程序产生进程过程
流程
在 Linux 中,程序产生进程的过程可以从内核层面的 task_struct 数据结构来介绍,该数据结构用于表示进程的详细信息。下面是大致的步骤:
创建进程:当执行一个程序时,内核会通过调用 fork() 系统调用来创建一个新的进程。fork() 系统调用会将当前进程的 task_struct 数据结构复制一份,创建一个与父进程几乎相同的子进程。
分配进程 ID:在创建进程后,内核会为该进程分配一个唯一的进程 ID(PID)以标识该进程。进程 ID 在整个系统范围内是唯一的。
设置进程状态:新创建的进程的初始状态通常是就绪状态(RUNNING),表示它已准备好并可以开始执行。
分配资源:进程创建后,内核会为它分配必要的资源,包括内存空间、文件描述符、栈大小等。这些资源信息会保存在 task_struct 数据结构中。
设置上下文:进程创建后,内核会为它设置初始的执行上下文,包括程序计数器(PC)和其他寄存器的值。这样,当进程被调度时,它可以从正确的位置开始执行。
加入调度队列:新创建的进程会被添加到就绪队列中,等待调度器将其分配给一个 CPU 并开始执行。
执行程序:一旦进程被调度执行,它将开始执行程序的指令,按照程序的逻辑进行操作。
从 task_struct 数据结构的层次上看,Linux 中程序产生进程的过程包括创建进程、分配进程 ID、设置进程状态、分配资源、设置上下文、加入调度队列以及执行程序的步骤。这些步骤确保了进程的正确创建和执行。
mm(内存管理)
mm,即 Memory Management,是操作系统内核中的一个组件,主要负责管理和控制计算机的内存资源。它的作用是确保各个进程能够共享内存资源,并且按需分配和回收内存。
mm 的主要功能包括以下几个方面:
内存分配和回收:mm 负责管理内存的分配和回收。它通过内存管理算法,将可用的内存空间分配给进程,以满足其运行时的内存需求。当进程释放内存时,mm 将回收该内存,并重新将其标记为可用。
虚拟内存管理
:mm 管理着进程的虚拟内存地址空间。它将虚拟地址映射到物理地址,并将内存分页成逻辑上连续的页帧,使得进程可以使用虚拟内存地址进行访问,而不需要了解物理内存的细节。内存保护:mm 负责处理内存保护相关的任务,如内存访问权限管理、页面写保护、页面换入换出等。它通过页表和访问控制位,确保进程只能访问其拥有权限的内存区域。
内存共享和进程间通信:mm 提供了内存共享机制,使得不同进程可以共享同一块内存区域。这为进程间的通信和数据共享提供了便利。
内存清理和回收:当系统的内存资源不足时,mm 负责清理不再使用的内存页面,并将其释放回系统,以便其他进程使用。这确保系统能够高效地利用有限的内存资源。
mm 是操作系统内核的核心组件之一,负责管理和控制计算机的内存资源,以满足进程的内存需求,保护进程的内存访问权限,并提供内存共享和进程间通信的机制。
程序数据段存储在程序的虚拟内存中
程序中的数据会保存在进程的虚拟地址空间中的不同区域:
栈(Stack):栈是用于存储函数调用、局部变量和函数参数的一种数据结构。每当一个函数被调用时,相关的函数参数和局部变量就会被保存到栈帧中,并随着函数的执行在栈上动态地分配和释放空间。
堆(Heap):堆是用于动态分配内存的区域。在程序中使用诸如malloc、calloc或new等函数/运算符来分配内存时,这些分配的内存区域就位于堆中。堆的内存管理是通过系统调用(如brk和mmap)来实现的。
数据段(Data Segment):数据段存储全局变量和静态变量。它包括了已初始化的全局和静态变量的内存。数据段在程序静态分配内存时分配,并且在程序运行期间保持不变。
BSS段(Block Started by Symbol):BSS段也存储全局变量和静态变量,但是这些变量在程序中未被显式初始化。BSS段在程序加载时会被初始化为零或空值。
总而言之,进程的虚拟地址空间中存在不同的区域用于存储程序的数据。栈用于保存函数调用和局部变量,堆用于动态分配内存,数据段存储已初始化的全局和静态变量,BSS段存储未显式初始化的全局和静态变量。我们可以童年过mm
来管理虚拟内存。
1.5进程的死亡
进程的死亡过程通常可以分为以下几个步骤:
退出请求:当进程完成了它的任务或者发生了无法继续执行的错误时,它会向操作系统发送退出请求。这可以是显式的退出调用,如
exit()
函数,或者是其他非正常退出的情况,如错误导致的崩溃。清理资源:在进程退出之前,它需要清理自己所占用的资源,包括关闭文件描述符、释放动态分配的内存、断开与其他进程的连接等。这些操作确保资源在进程终止后可以被回收并重新使用。
发送终止信号:进程在准备终止时,会向其父进程发送一个终止信号。这通知父进程进程正在退出,并且父进程可以作出相应的处理,如清理子进程的相关资源。
执行终止处理程序:在实际退出之前,进程会执行一些终止处理程序,这些程序可以由进程自身定义。例如,释放进程使用的其他资源、保存日志、发送通知等。
进程终止:最后,进程正式终止,并从操作系统的进程表中被移除。此时,进程的内存、打开的文件描述符、I/O缓冲区等会被系统回收和清理。
需要注意的是,进程的死亡过程也可能受到其他因素的影响,如操作系统的终止信号、内存不足等。在这些情况下,进程可能会被强制终止,而不经过正常的退出流程。
- 点赞
- 收藏
- 关注作者
评论(0)