LinuxKernelDevelopment_读书笔记

一.内核概念
1.CPU在任何时间点上的活动都处于如下情况中:
A.运行于内核空间, 在进程上下文中
B.运行于内核空间, 在中断上下文中
C.运行于用户空间, 在用户进程中
即使CPU空闲时,它也在某个空进程中,属于A情况

2.IPC--进程间通信


3.Linux内核版本只分两种: 稳定版 和 开发版
版本命名采用三段式: 主版本.从版本.修订版 (从版本为偶数表示稳定版, 奇数则为开发版, 如2.6.3则为稳定版)
主版本和从版本一起构成"内核系列", 如2.6版内核系列

4.内核栈是固定的, 32位机的内核栈为8KB, 64位机的内核栈为16KB


5.同步和并发: 当并发的访问共享数据时,就要求有同步机制保证不会出现竞争条件
如:多处理器系统中, 多个处理器同时访问同一个资源
如:中断异步到来时, 当前正在访问某个资源, 而中断处理也是去访问该资源

解决竞争的常用方法: 自旋锁 和 信号量


二.进程管理
6.进程(Linux中也叫任务task):
A.不仅仅包含可执行程序代码段, 还包含用到的其他资源, 如打开的文件, 挂起的信号, 内核内部数据, 处理器状态, 地址空间, 一个或多个线程等.
B.程序本身并不是进程, 进程 = 处于执行期的程序 + 包含的所有资源, 可以简单地抽象理解为Gradle概念的SourceSet.
C.实际上多个进程完全可能执行的是同一个程序, 并且多个进程也可以共享如文件, 地址空间等资源.

7.进程的创建:
调用fork()系统调用通过复制一个现有进程来创建一个全新的进程, 而调用者称为父进程, 创建出来进程称为子进程. 接着调用exec*()这族函数创建新地址空间, 并把可执行文件载入到该地址空间中执行.
一旦fork()函数执行结束时, 父进程恢复执行, 子进程开始执行.
所有的进程都是PID为1的init进程的后代, 故每个进程必有一个父进程, 相应的, 每个进程可有0个或多个子进程
拥有同一个父进程的所有进程称为兄弟, 进程间的关系存放在进程描述符中, 故可通过这种继承体系从任意进程出发查找到任意指定的其他进程.

注: Linux中创建进程采用 写时拷贝(copy-on-write) 技术, 即调用fork()时, 内核并不复制整个父进程地址空间, 而是让父进程以只读的方式共享给子进程, 只有当子进程
中的页需要写入时, 父进程中的数据才会被复制, 这种技术使得地址空间上页的拷贝被推迟到实际发生写入的时候才进行.
故在页不需要被写入的情况下, 如fork()后立即调用exec(), fork()的实际开销仅是为子进程创建唯一的进程描述符

clone()函数是fork()的实现. 故调clone()与fork()是一样的

新创建的子进程与父进程平分父进程剩余的时间片.

8.进程的结束:
调用exit()系统调用结束进程, 释放其占用的资源(但仍保留进程描述符, 供父进程获知它的信息, 只有当父进程通知内核它并不关注那些信息后, 进程描述符才会被释放), 并告知父进程. 
父进程也可以通过wait4()系统调用来查询子进程是否结束, 这使得父进程拥有等待子进程执行完毕的能力.
进程结束后被设置为僵死状态, 直到父进程调用wait()或waitpid()为止.

9.孤儿进程:
如果父进程在子进程之前退出, 则子进程退出时永远处于僵死状态, 白白耗费内存.
解决: 给子进程在当前线程组内找一个线程作为父亲, 如果不行, 就让init进程做为它们的父进程.

9.线程:
是进程中的活动对象, 每个线程都拥有独立的程序计数器, 进程栈, 进程寄存器. 内核调度的对象是线程, 而不是进程.
而Linux并不对线程和进程做特别区分, 认为线程只不过是一种特殊的进程, 每个线程都拥有自己唯一的进程描述符.
故对内核来说, 线程就是一个普通的进程(只是该进程与其他进程共享某些资源, 如地址空间, 打开的文件等)

10.线程的创建:
与进程的创建一样, 唯一的区别仅在于调用clone()时, 需传递一些参数来指明哪些资源被共享.
如: clone(CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, 0) 表明父子俩共享地址空间, 文件系统资源, 文件描述符, 信号处理程序
即: 对Linux内核来说, 在创建新进程时, 若指明了共享资源, 则新创建的子进程就是所谓的线程.

11.进程的两种虚拟机制: 虚拟处理器 和 虚拟内存
虚拟处理器: 虽然实际上可能是许多进程正在共用一个处理器, 但虚拟处理器给进程一种假象, 让这些进程觉得自己在独享处理器
虚拟内存:   让进程在获取和使用内存时觉得自己拥有整个系统的所有内存资源

注: 同一个进程中的多个线程可以共享虚拟内存, 但拥有各自的虚拟处理器.

12.进程描述符:
内核把所有进程存放在 任务队列(task list) 的双向循环链表中, 该链表中的每一项都是 进程描述符 的结构, 
进程描述符包含一个具体进程的所有信息, 如PID, 打开的文件, 地址空间, 挂起的信号, 进程状态, 进程间关系等

13.PID:
内核通过一个唯一的进程标识值PID(process identification value)来标识每个进程, PID可取的最大值表示系统允许同时存在的进程最大数
由于任务队列是双向循环链表, 故PID最大值越小, 转一圈就越快

14.进程状态: 每个进程都必然处于五种进程状态中
A.运行(Task_Running)--------------位于可执行队列中
B.可中断(Task_Interruptible)------休眠的一种, 如果接收到一个信号会被提前唤醒并响应该信号, 不一定非要等到事件来唤醒, 即伪唤醒
C.不可中断(Task_Uninterruptible)--休眠的另一种, 会忽略信号, 只能由事件唤醒, 它和B位于同一个等待队列中
D.僵死(Task_Zombie)-----指进程调用exit()之后的状态, 内核释放其占用的资源, 不再投入运行, 但仍保留进程描述符供父进程获知其信息
E.停止(Task_Stopped)----指D状态的进程, 且父进程通知内核它并不关注其信息后, 内核进一步释放剩余的进程描述符, 真正死亡

三.进程调度
15.进程调度本质: 是使所有进程有效工作的代码段, 故也称调度程序.

16.进程调度功能: 负责选择下一个要运行的进程, 负责分配CPU的时间资源.
即只要系统中进程数比处理器数多, 在某指定时刻必然有一些进程在等待执行, 在这些等待进程中选择一个来执行, 是进程调度的基本工作.

17.单处理器: CPU在多个进程间切换执行, 对用户层面会产生多个进程同时运行的幻觉, 并不是真正意义上的并行.
  多处理器: 多个进程在不同的处理器上真正同时, 并行地运行.
  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值