“把书读薄”系列之《Understanding the Linux Kernel》:Chapter 1 - Introduction

这是“‘把书读薄’系列之《Understanding the Linux Kernel》”的第一篇。(注:本文讨论范围若未经特别说明,均和书籍一样,针对的是Linux 2.6.11版本)

在这一篇中

由于第一章主要是概论,并没有深入的探讨Linux的一些机制,所以我就只会列举一些通过这一章我学习到的,我认为对于Linux而言重要的或者容易忽视的特性,在需要的地方我会适当的展开讨论。

  1. Linux是宏内核,支持LKM(Loadable Kernel Module)。
  2. Linux虽然是宏内核,但也有少量(a few)的内核线程周期性的专门执行着几个内核函数(个人感觉这有点像微内核的特性),内核线程只运行在内核态,它们不表示系统中的执行上下文。
  3. Linux依靠轻量级进程(Light Weight Process,LWP)来实现多线程应用,每个线程实际上是一个轻量级进程,它们是系统中最基本的执行上下文,有自己的用户栈和内核栈。
  4. Linux是可抢占式内核,一个被中断的处于内核态的进程同样可以被嵌套中断,然后被切换到别的进程。
  5. Linux在文件系统上又加了一层“虚拟文件系统”,可以让Linux轻松的挂载各种不同的文件系统。
  6. Linux从2.6开始不再遵从中间的数字是偶数则是稳定版本,是奇数则为开发中版本。
  7. 每个文件都只属于一个user和一个group。
  8. 微内核的优缺点:
    优点:
    1.迫使系统编程者采用模块化的方法,产生定义良好的程序接口。
    2.移植性更好,因为对于所有硬件依赖的组件可以单独放置到微内核代码中。
    3.内存使用效率更高,不需要的系统进程可以终止,从而释放内存空间。
    缺点:
    1.进程间通信有开销(这也是为什么Linux依然采用宏内核的原因)
    2.并发度存在瓶颈。
  9. Linux依靠LKM同样可以近似实现微内核上述三个优点。
  10. 不能为文件夹创建硬链接,否则有可能会使目录树变成一个环形图,这样会导致一些bug,比如在执行find命令时,会陷入死循环。
  11. 硬链接只能在同一个文件系统中创建。
  12. Linux将文件的信息和文件的内容区分开来,Linux为每个文件分配了一个inode用以表示这个文件的相关信息。
  13. Linux内核是可重入的(见上述第4条),这是很重要的——这会让内核及时响应外设发出的中断,使外设在中断被响应后能继续做其他的事情。
  14. Linux靠信号量和上锁来实现同步。为了防止死锁,Linux只允许进程按序申请资源
  15. Linux使用自旋锁来解决多处理器间的临界资源访问问题。自旋锁和信号量类似,只是没有等待队列,因为它并不是通过挂起进程,而是通过使进程不断执行一个紧凑的循环来使进程等待,直到等待的资源被别的处理器释放。
  16. 为什么单处理器不使用自旋锁的方式?(个人思考)
    答:对于单处理器,使用semaphore的开销是“挂起+唤醒进程”的时间,使用自旋锁的开销是“时间片*n”(n的值等于其他进程释放这个资源前,等待这个自旋锁的进程获得了几次cpu),相比较而言前者时间通常更短。
  17. Linux的进程间通信方式:信号,管道,有名管道,消息队列,信号量,共享内存。
  18. Linux的进程是既知道其父进程也知道其子进程的。(进程描述符中有记录)
  19. 在一个进程终止后,而在它的父进程调用wait()类系统调用前,这个进程被称作zombie进程,它的进程描述符依然残留在内存里,这么做是为了父进程能对其中的一些信息进行检查。之后当父进程执行wait()类系统调用时,这些已退出的子进程由EXIT_ZOMBIE状态变为EXIT_DEAD状态,系统这时才会回收它们的进程描述符。
  20. 若某个父进程没有执行wait()类系统调用就退出,则内核会让这个父进程的子进程成为init进程的子进程,防止系统中残留大量的zombie进程。
  21. 每个设备文件对应一个特定的设备驱动。