C的优点
- C提供了大量的控制能力,C可以完全控制内存分配与释放。
- C几乎没有隐藏的代码,几乎可以在阅读C代码的时候想象到对应的RISC-V机器指令是什么。
- 通过C可以直接访问内存,可以读写PTE的bit位或者设备寄存器。
- 使用C会有极少的依赖,因为你不需要一个大的程序运行时。你几乎可以直接在硬件上运行C程序。你们可以在XV6启动过程中看到这一点, 只通过几行汇编代码,你就可以运行C代码。
C的缺点
很难写出安全的C代码。这里存在各种各样的Bug,
- 首先是最著名的buffer overrun,比如说数组越界,撑爆了Stack等等。
- 其次是use-after-free bugs,你可能会释放一些仍然在使用的内存,之后其他人又修改了这部分内存。
- 当线程共享内存时,很难决定内存是否可以被释放。
高级编程语言的优点
- 提供了memory-safety:要么当它们发生时程序运行时会检查数组是否越界,如果越界了就panic;要么高级编程语言不允许你写出引起Bug的代码,所以上一节中问题完全不可能出现。
- 类型安全
- 通过GC实现了自动的内存管理,所以free更容易了,你都不用去考虑它,GC会为你完成所有的内存释放工作
- 对并发更友好
- 有更好的抽象,接口和类等面向对象的语法使得你可以写出更加模块化的代码。
高级编程语言的缺点
- 高级编程语言通常有更差的性能。高级编程语言通常都有一些额外的代价,这被称为High Level Language Tax。比如说在索引一个数组元素时检查数据边界,比如说检查空指针,比如说类型转换。除此之外,GC也不是没有代价的,需要花费一些时间来跟踪哪些对象可以被释放。
- 除了性能之外,高级编程语言与内核编程本身不兼容。
- 比如说高级编程语言没有直接访问内存的能力,因为这从原则上违反了Type safety。
- 高级编程语言不能集成汇编语言,而在内核中的一些场景你总是需要一些汇编程序,比如说两个线程的context switching,或者系统启动
- 编程语言本身支持的并发与内核需要的并发并不一致,比如我们在调度线程的时候,一个线程会将锁传递给另一个线程。一些并发管理模式在用户程序中不太常见,但是在内核中会出现。