CPython 实现原理
  • README
  • 一、简介
    • 1.1 如何使用此书
    • 1.2 额外材料和学习资料
  • 二、获取 CPython 源码
    • 2.1 源代码里有什么?
  • 三、准备你的开发环境
    • 3.1 选IDE还是编辑器?
    • 3.2 安装Visual Studio
    • 3.3 安装Visual Studio Code
    • 3.4 安装JetBrains Clion
    • 3.5 安装Vim
    • 3.6 总结
  • 四、编译 CPython
    • 4.1 在 macOS 上编译 CPython
    • 4.2 在 Linux 上编译 CPython
    • 4.3 安装自定义版本
    • 4.4 make 快速入门
    • 4.5 CPython 的 make 目标
    • 4.6 在 Windows 上编译 CPython
    • 4.7 PGO 优化
    • 4.8 总结
  • 五、Python 语言和语法
    • 5.1 为什么 CPython 是用 C 语言而不是用 Python 语言来实现
    • 5.2 Python 语言规范
    • 5.3 分析器生成器
    • 5.4 重新生成语法
    • 5.5 总结
  • 六、配置和输入
    • 6.1 配置状态
    • 6.2 构建配置
    • 6.3 从输入构建模块
    • 6.4 总结
  • 七、基于语法树的词法分析和解析
    • 7.1 具象语法树生成器
    • 7.2 CPython 解析器-分词器
    • 7.3 抽象语法树
    • 7.4 要记住的术语
    • 7.5 一个示例:添加一个约等于比较运算法
    • 7.6 总结
  • 八、编译器
    • 8.1 相关源文件
    • 8.2 重要的专业术语
    • 8.3 实例化一个编译器
    • 8.4 未来标志和编译器标志
    • 8.5 符号表
    • 8.6 核心编译过程
    • 8.7 汇编
    • 8.8 创建一个 Code Object
    • 8.9 使用 Instaviz 展示 Code Object
    • 8.10 一个示例:实现约等于操作符
    • 8.11 总结
  • 九、求值循环
    • 9.1 构建线程状态
    • 9.2 构建帧对象
    • 9.3 帧的执行
    • 9.4 值栈
    • 9.5 例子:在列表中添加元素
    • 9.6 总结
  • 十、内存管理
    • 10.1 C 中的内存分配
    • 10.2 Python 内存管理系统设计
    • 10.3 CPython 内存分配器
  • 十一、并行和并发
    • 11.1 并行和并发模型
    • 11.2 进程的结构
    • 11.3 多进程并行
    • 11.4 多线程
    • 11.5 异步编程
    • 11.6 生成器
    • 11.7 协程
    • 11.8 异步生成器
    • 11.9 子解释器
    • 11.10 总结
  • 十二、对象和类型
    • 12.1 本章的例子
    • 12.2 内置类型
    • 12.3 对象和可变长度对象类型
    • 12.4 类型类
    • 12.5 布尔和整数类型
    • 12.6 Unicode 字符串类型
    • 12.7 字典类型
    • 12.8 总结
  • 十三、标准库
    • 13.1 Python 模块
    • 13.2 Python 和 C 模块
  • 十四、测试套件
    • 14.1 在 Windows 上运行测试套件
    • 14.2 在 Linux 或 MacOS 上运行测试套件
    • 14.3 测试标志
    • 14.4 运行特定测试
    • 14.5 测试模块
    • 14.6 测试工具
    • 14.7 总结
  • 十五、调试
  • 十六、基准测试、性能分析和追踪
  • 十七、下一步计划
    • 17.1 为 CPython 编写 C 扩展
    • 17.2 改进你的 Python 应用程序
    • 17.3 为 CPython 项目做贡献
    • 17.4 继续学习
  • 十八、附录
    • 18.1 C 预处理器
    • 18.2 基础 C 语法
    • 18.3 总结
  • 致谢
Powered by GitBook
On this page
Edit on GitHub
  1. 十一、并行和并发

11.2 进程的结构

Windows、macOS 或 Linux 等操作系统的任务之一是控制正在运行的进程。这些进程可以是浏览器或 IDE 等 UI 应用程序,也可以是网络服务或操作系统服务等后台进程。

为了控制这些进程,操作系统提供了用于启动新进程的 API。创建进程时,操作系统会对其进行注册,以便知道哪些进程正在运行。进程被赋予了唯一的 ID (PID)。根据操作系统的不同,它们可以具有几个其他属性。

POSIX 进程具有在操作系统中注册的最小属性集:

  • 控制终端;

  • 当前工作目录;

  • 有效组 ID 和有效用户 ID;

  • 文件描述符和文件模式创建掩码;

  • 进程组 ID 和进程 ID;

  • 真实组 ID 和真实用户 ID;

  • 根目录。

你可以在 macOS 或 Linux 中通过运行 ps 命令查看运行的进程的这些属性。

参见

IEEE POSIX 标准(1003.1-2017)定义了进程和线程的接口和标准行为。

Windows 具有类似的属性列表,但设置了自己的标准。Windows 文件权限、目录结构和进程注册表与 POSIX 有很大不同。

Windows 进程由 Win32_Process 表示,其可以在 WMI、Windows Management Instrumentation 运行时或使用任务管理器查询。

在操作系统上启动一个进程后会得到:

  • 用于调用子程序的栈内存;

  • 堆(参见“C 中的动态内存分配”);

  • 操作系统上文件、锁和套接字的访问途径。

当进程执行时,计算机上的 CPU 还会保留其他数据,如:

  • 一个寄存器保存了当前正在执行的指令或进程因该指令所需的其他任何数据;

  • 一个指令指针或程序计数器指示了程序序列中哪条指令正在执行。

CPython 进程包括已编译的 CPython 解释器和已编译的模块。这些模块在运行时加载并通过 CPython 求值循环转换为指令:

图片内容: Process:进程, Stack:栈, Heap:堆, Process Memory:进程内存, Python Objects:Python 对象, Instructions:指令, CPython Runtime:CPython 运行时, Compiled Modules:编译模块, Files:文件, Locks:锁, Sockets:套接字

程序寄存器和程序计数器指向进程中的单个指令。这意味着在任何时候只能执行一条指令。对于 CPython 而言,这意味着在给定时间只能执行一条 Python 字节码指令。

有两种主要方法允许在进程中并行执行指令:

  1. fork 另一个进程。

  2. spawn 一个线程。

现在你已经回顾了进程的构成,可以探索 fork 和 spawn 子进程了。

Previous11.1 并行和并发模型Next11.3 多进程并行

Last updated 2 years ago