程序从加载到运行的过程
程序从加载到运行的过程主要包括以下几个步骤:程序启动、加载、链接、执行。这一过程涉及操作系统、编译器、链接器等多个系统组件的协作。
# 程序启动
当用户或系统决定运行一个程序时,会通过命令行、图形界面、脚本或其他方式发起程序的启动请求。操作系统收到这个请求后,会进行以下处理:
- 创建进程:操作系统为该程序创建一个新的进程,为其分配以恶搞唯一的进程ID
- 分配资源:为该进程分配所需资源,包括内存、文件描述符、CPU时间片等
# 程序加载
加载指程序的可执行文件从存储介质(如硬盘)加载到内存中。这个过程通常由操作系统的程序加载器(Loader)来完成:
- 读取可执行文件:程序加载器读取可执行文件,解析出程序的各个段(代码段,数据段等)
- 分配内存空间:操作系统为程序分配内存空间,并将各段加载到对应的内存区域
- 代码段:包含程序的及其指令
- 数据段:包含已初始化的全局变量以及静态变量
- 堆:用于动态内存分配
- 栈:用于函数调用、局部变量存储
# 程序链接
链接分为静态链接和动态链接:
- 静态链接:在编译时将所有依赖库文件和模块直接合并到生成的可执行文件中。这样生成的可执行文件时自包含的
- 动态链接:在程序运行时,链接器(动态链接器或动态加载器)会将程序需要的共享库(动态链接库)加载到内存中,并将这些库中的符号解析到程序的地址空间中。动态链接有助于节省内存和磁盘空间,并允许库的更新无需重新编译应用程序
# 程序执行
一旦程序被成功加载和链接,操作系统将其控制权交给程序的入口点(通常时main
函数),开始执行程序的指令:
- 初始化:程序的初始化代码运行,设置运行环境,如设置堆栈指针,初始化全局变量等
- 执行主逻辑:程序从入口开始执行其主要逻辑部分
- 函数调用和栈管理:程序执行过程中,函数调用和返回会动态调整栈的内容
- 系统调用:程序在需要与操作系统交互时,会执行系统调用,如文件操作、内存管理等。
# 程序终止
程序执行完毕后,会通过以下几种方式终止:
- 正常终止:程序正常运行结束,通常通过调用
exit
函数或者返回主函数main
- 异常终止:程序由于未处理的异常(如段错误、非法操作等)被操作系统终止
- 强制终止:外部因素(如用户终止命令、系统关闭)导致程序被强制终止
程序终止后,操作系统会进行以下清理工作:
- 释放资源:回收进程占用的所有资源,包括内存、文件描述符等等
- 通知父进程:向创建该进程的父进程发送终止信号,以便父进程可以获取子进程的退出状态。
上次更新: 2024/07/08, 18:44:07