9. C 标准库和实现

操作系统为我们提供了对象和操作它们的 API:我们学习了进程管理的 fork, execve, exit, waitpid;内存管理的 mmap;文件 (对象) 管理的 open, read, write, dup, close, pipe, ……大家观察到这些 API 的设计有一个有趣的原则:“非必要不实现” (“机制与策略分离”、“最小完备性原则”):但凡应用程序能自己搞定的功能,操作系统就不需要提供——在一定程度上,这样的设计能防止 “包揽一切” 导致代码膨胀,甚至在长期演化的过程中成为历史的包袱。

本讲内容:在操作系统 API 之上,为了服务应用程序,毋庸置疑需要有一套 “好用” 的库函数。虽然 libc 在今天的确谈不上 “好用”,但成就了 C 语言今天 “高级的汇编语言” 的可移植地位,以 ISO 标准的形式支撑了操作系统生态上的万千应用。

9.1 libc 简介

💬
Prompt: 为什么称 C 语言是高级的汇编语言?
💬
Prompt: 我希望学习 libc 中一些重要函数的实现,但 glibc 太复杂了。有哪些更简单的 libc,让我能链接、调试库的代码?

9.2 基础编程机制的抽象

💬
Prompt: 解释 C 标准库中的 offsetof,以及它有什么应用?

9.3 系统调用与环境的抽象

9.4 动态内存管理

9.5 总结

Take-away Messages: 在系统调用和语言机制的基础上,libc 为我们提供了开发跨平台应用程序的 “第一级抽象”。在此基础上构建起了万千世界:C++ (扩充了 C 标准库)、Java、浏览器世界……今天,C 语言在应用开发方面有很多缺陷,但仍然为 “第一级抽象” 提供了一个有趣的范本:

🖥️编程

试着浏览 libc 的头文件/手册,找到你认为有趣的函数,并且观察 musl 是如何实现的。

📚阅读材料

教科书 Operating Systems: Three Easy Pieces:

  • 第 17 章 - Free Space Management
  • 第 18 章 - Introduction to Paging 🌶️
  • 第 19 章 - Translation Lookaside Buffers 🌶️
  • 第 20 章 - Advanced Page Tables 🌶️
  • 第 21 章 - Swapping: Mechanisms 🌶️
  • 第 22 章 - Swapping: Policies 🌶️
  • 第 23 章 - Complete VM Systems 🌶️