期末总结
第一部分 课程进行知识点总结
进程的启动和进程的切换机制:
初始化进程的数据结构 (可以初始化很多进程)start开始执行0号进程
搭建好CPU运行环境(进程搭建好堆栈和建立好入口), 完成了内核的初始化
ret 之后进程正式启动
如何切换?: switch to next process
将当前进程的ebp保存起来 当前进程的esp保存起来 把next进程的sp放在esp中 保存eip 将下一个进程的eippush到栈里 即可切换进程
“操作系统是如何工作的:操作系统工作的两个关键: 中断和进程上下文的切换 将C代码转化为机器代码后 开始在CPU 中执行 而在执行过程中遇到中断时 需要靠CPU和内核代码来共同实现保存现场和恢复现场
计算机三个法宝:
1、存储程序计算机
2、函数调用堆栈
3、中断
本周中得知
操作系统两把宝剑:
1、中断上下文的切换:保存现场和恢复现场
2、进程上下文的切换
Linux内核简介
1.3 操作系统和内核简介
操作系统 :是指在整个系统中负责完成最基本功能和系统管理的那些部分 它包括:内核 设备驱动 启动引导程序 命令行shell或者其他种类的用户界面 基本的文件管理工具和系统工具
内核:由负责响应中断的中断服务程序,负责管理多个进程从而分享处理器的时间调度程序,负责管理进程地址空间的内存程序和网络,进程间通讯等系统服务程序共同组成
处理器的活动必然其下三者之一:
- 运行于用户空间,执行用户进程
- 运行于内核空间,处于进程上下文,代表某个特定的进程执行
1.4 Linux内核与传统内核的比较
• 单内核与微内核设计之比较
• 单内核是一种较为简单的设计 所有的内核都设计成单内核 单内核就是把它从整体上作为一个单独的大过程来实现 同时也运行在一个单独的地址空间上 所有的内核服务都是在这样的一个大内核地址空间上运行 。
(内核之间的通信是微不足道的 )
- 微内核
- 内核按功能被划分成各个独立的过程。每个过程独立的运行在自己的地址空间上。
- 微内核
- 内核按功能被划分成各个独立的过程。每个过程独立的运行在自己的地址空间上。
- 优点:安全。内核的各种服务独立运行,一种服务挂了不会影响其他服务。
- 缺点:内核各个服务之间的调用涉及进程间的通信,比较复杂且效率低。
- 微内核
2.3 编译内核
配置选项(指定内核源码可以访问的值,一般以预处理宏的形式表示)
• 决定哪些文件编译进内核;通过预处理命令处理代码。
• .二选一:yes/no
• 三选一:yes(把代码编译进主内核映像中)/no/module(该配置项被选定了)【驱动程序一般是三选一】
• 可以是字符串或整数 - 配置工具: $ make config 配置命令解释器,最简单的一个字符界面下的命令行工具; $ make menuconfig 配置用户界面,基于ncurse库的图形界面工具; $ make gconfig 基于gtk+的图形工具; $ make defconfig 基于默认的配置为个人的体系结构创建一个配置; $ make oldconfig 验证和更新配置; - .config文件:配置项会被存放在内核代码树根目录下。
2.4 内核开发的特点
内核编程时既不能访问C库也不能访问标准的C头文件
内核编程时必须使用GNU C
内联函数: 函数会在所调用的位置上展开。 定义时,需要使用static作为关键字,用inline限定它。 内联函数必须在使用之前就定义好,一般在头文件中定义。 内核中优先使用内联函数而不是宏。
内联汇编: 通常使用asm()指令嵌入汇编代码,用volatile表示不优化
分支声明: unlikely(x) - x很少出现,绝少发生,通常为假 likely(y) - y经常出现,通常为真
内核编程时缺乏像内存空间那样的内存保护机制
难以执行浮点运算
考虑可移植的重要性
进程
进程就是处于执行期的程序。
进程就是正在执行的程序代码的实时结果。
进程是处于执行期的程序以及相关的资源的总称。
进程包括代码段和其他资源。
线程
执行线程,简称线程,是在进程中活动的对象。
内核调度的对象是线程而不是进程。
Linux对线程并不特别区分,视其为特殊的进程。
虚拟处理器和虚拟内存
在现代操作系统中,进程提供两种虚拟机制:虚拟处理器和虚拟内存。
包含在同一个进程中的线程可以共享虚拟内存,但是每个都拥有各自的虚拟处理器。
几个函数
- fork():创建新进程
- exec():创建新的地址空间并把新的程序载入其中clone():
- fork实际由clone实现exit():退出执行
- wait4():父进程查询子进程是否终结
- wait()、waitpid():程序退出执行后变为僵死状态,调用这两个消灭掉。
进程上下文
内核“代表进程执行”并处于进程上下文时,上下文中current宏是有效的,除非在此间隙有更高优先级的进程需要执行并由调度器做出了相应调整,否则在内核退出的时候,陈谷恢复在用户空间会继续执行。
程序执行系统调用或者触发异常后,会陷入内核空间,这时候内核代表进程执行,并且处于进程上下文中。
进程对内核的访问必须通过接口:系统调用和异常处理程序。
进程家族树
所有的进程都是pid为1的init进程的后代。
内核在系统启动的最后阶段启动init进程。
系统中的每一个进程必有一个父进程,可以拥有0个或多个子进程,拥有同一个父进程的进程叫做兄弟。
这种关系存放在进程描述符中,parent指针指向父进程task_struct,children是子进程链表。
线程在Linux中的实现
线程机制是现代编程技术中常用的一种抽象概念,该机制提供了在同一程序内共享内存地址空间运行的一组线程,可以共享打开的文件和其他资源,支持并发程序设计,在多处理器系统上可以保证真正的并行处理。
Linux内核的角度来看并没有线程这个概念,它把所有线程都当做进程来实现,线程仅仅被视为一个与其他进程共享某些资源的进程。
对于Linux来说,线程只是一种进程间共享资源的手段。
进程终结
进程终结时,内核必须释放它所占有的资源并告知父进程。
进程终结的原因:一般是来自自身,发生在调用exit()系统调用时。
- 显式的调用
- 隐式的从某个程序的主函数返回
一、调度时机
不同类型的进程有不同的调度需求
第一种分类:
I/O-bound
频繁的进行I/O
通常会花费很多时间等待I/O操作的完成
CPU-bound
计算密集型
需要大量的CPU时间进行运算
第二种分类
批处理进程(batch process)
不必与用户交互,通常在后台运行
不必很快响应
典型的批处理程序:编译程序、科学计算
实时进程(real-time process)
有实时需求,不应被低优先级的进程阻塞
响应时间要短、要稳定
典型的实时进程:视频/音频、机械控制等
交互式进程(interactive process)
需要经常与用户交互,因此要花很多时间等待用户输入操作
响应时间要快,平均延迟要低于50~150ms
典型的交互式程序:shell、文本编辑程序、图形应用程序等
二、进程调度的时机
中断处理过程(包括时钟中断、I/O中断、系统调用和异常)中,直接调用schedule(),或者返回用户态时根据need_resched标记调用schedule();
用户态进程只能被动调度。
内核线程可以直接调用schedule()进行进程切换,也可以在中断处理过程中进行调度,也就是说内核线程作为一类的特殊的进程可以主动调度,也可以被动调度;
内核线程是只有内核态没有用户态的特殊进程。内核线程可以主动调度,也可以被动调度。
用户态进程无法实现主动调度,仅能通过陷入内核态后的某个时机点进行调度,即在中断处理过程中进行调度。
schedule()函数选择一个新的进程来运行,并调用context_switch进行上下文的切换,这个宏调用switch_to来进行关键上下文切换
next = pick_next_task(rq, prev);//进程调度算法都封装这个函数内部
context_switch(rq, prev, next);//进程上下文切换
switch_to利用了prev和next两个参数:prev指向当前进程,next指向被调度的进
第二部分 学习心得体会
从寒假开始学习孟宁老师这门课 ,计算机是如何调用到内核操作系统再到各种函数调用 学习的难度越来越大 其实很多地方都搞不明白 但是通过寻求同学的帮助解决了一些问题 坚持做每一次的实验 写总结 自己也得到了一定的提升 。 很多事情贵在坚持 没有完全解决不了的事情 只要耐心的坚持下来 就一定有收获
第三部分 全部作业的博客链接
http://www.cnblogs.com/20135331wenyi/p/5400275.html
http://www.cnblogs.com/20135331wenyi/p/5372334.html
http://www.cnblogs.com/20135331wenyi/p/5349551.html
http://www.cnblogs.com/20135331wenyi/p/5349506.html
http://www.cnblogs.com/20135331wenyi/p/5320664.html
http://www.cnblogs.com/20135331wenyi/p/5294924.html
http://www.cnblogs.com/20135331wenyi/p/5262471.html
http://www.cnblogs.com/20135331wenyi/p/5209990.html