最近看了下《计算机操作系统设计与实现 第三版》 感觉写的很棒(PS:虽然目前还没看完·尴尬脸·)
同时感觉自己也收获了很多 以前都没认真学过 写一份总结给自己当做对操作系统的扫盲吧~
以下内容纯粹是自己个人的理解与整理~
计算机的组成
- 首先最底层是硬件设备(主板 硬盘 电子元件 内存条 CPU 显卡 等等) 至于最底层的硬件是怎么工作的就不知道了(因为牵扯到电气工程学 想想老爱因斯坦也折腾过 这些玩意一辈子估计也学不完)
- 硬件设备上是微结构体(比如CPU里的寄存器)就是这些东西接受电气信号来操作硬件的
- 在上面就是机器语言 汇编一类的吧 用来发送信息操控硬件
- 在机器语言上面就是操作系统(Windows.Linux等)操作系统其实就是封装了对底层硬件的操作
留出一些基本的接口给外面 好让程序猿这群生物来做开发设计 不用老是考虑硬件的东东 不然累死他们了啊 - 操作系统上面是系统应用 (比如shell 编译器等等)这些都是不可更改的
- 在上面就是我们用的用户级应用了(比如QQ 网易云音乐..)这些都是为了解决某些实际 或者满足某些需求而设计的应用
操作系统的概念
- 操作系统提供了一系列服务和接口 让用户程序可以很方便的调用底层硬件(这些接口服务称为系统调用 System Call)
- 操作系统还提供资源管理的功能 包括分配磁盘 跟踪记录磁盘块等 不然怎么保证每次操作的数据完整和可靠
进程的概念
- 进程简单点讲就是一个正在运行的程序 他会有一块内存地址 他可以操作这块内存读写等 这块内存中存有他的程序、程序数据、堆栈
- 当进程被挂起后 在恢复的时候 要能接着他上次挂起时候的状态继续执行 才能保证整个进程的完成 是怎么做的呢?操作系统中有一张表 称为进程表(process table)这个表里记录了每个进程的数据外的所有信息(进程数据是在他占用的内存里啊!!)
被挂起的进程主要有2个信息
- 进程的地址空间 称为 内核映像 core image
- 进程表项 包含寄存器值和其他信息
一个进程可以创建一个或多个其他进程(称为子进程) 这些子进程又可以创建他们自己的子进程 这样就行程了一棵树 如下图
有时这些进程间需要互相通信访问数据等 这种通信称为 进程间通信 interprocess communication
文件
- 操作系统有一个主要功能就是屏蔽磁盘和其他IO操作的细节
给程序猿提供一个简洁与设备无关的文件模型
很显然系统需要帮我们处理很多
这时设计的系统调用有 创建文件 删除文件 读取文件 写入文件等
在读一个文件前还需要打开文件 在操作完后还需要关闭他这些都需要相应的系统调用来完成操作 - 当我们需要使用系统调用来创建一个目录以及把某一个文件放到一个指定目录 或者删除一个指定目录的文件这样就得到一个层次结构也就是文件系统
进程和文件树的区别
- 进程树的层次结构一般不会太深 3层已经很多了,而文件树的层次可以很深6层+都有
- 进程间的层次结构是短暂的一般几分钟 执行完就关闭了,而文件树的层次结构会很久 几年都可以
- 在所有者和保护方面 进程只有父进程可以访问控制子进程,而文件和目录除了所有者别的用户也可以访问
文件系统
- 以Minix3系统为例 文件和目录的保护机制是有一个11位的二进制码来保护的。
保护码包含三个3位的域 分别来描述其所有者、同组用户、其他用户的访问权限。
这一个3位域 分别由1位标识读取权限 1位标识写的操作权限 1位标识执行的权限
也就是传说中的rwx
其中x的可以执行权限一般来讲就是可以访问 可以搜索之类 - 在对一个文件进程读写的时候 系统需要先打开他这个时候需要进程访问权限的判断
如果访问权限是允许的 这个时候将会返回一个整数 称为文件描述符 如果没有访问权限将会返回一个错误码(-1) - 文件系统的挂载 对于大多数个人计算机而已都配有一个CD-ROM去东区( 类似光驱的玩意)
还是以Minix3系统为例 操作系统允许将光驱上的文件挂载到主文件树上。
在进行mount挂载系统调用之前 在硬盘上一个根文件系统 在CD-Rom上也有一个文件系统 这2个还没挂载的时候是互相对立互不干扰的。
在没有挂载的时候CD-ROM中的文件也是不能访问的 (因为没有路径啊)。
程序猿可以使用mount系统调用吧CD-ROM下的文件挂载到根文件系统的任意一个位置 如下图
这个图展示了把驱动中的x
和y
挂载到b
目录下 设备文件(special file) 设备文件的目标是使IO设备操作起来更类似文件。
这样对设备的读写就可以和文件读写调用相同的系统调用。
设备文件分为2类- 一是块设备文件(block special files)
- 一个是字符设备文件(character special files)。
设备文件描述的是以随机访问数据块为单元的设备 比如硬盘。
字符设备文件是以字符流方式进行操作的文件 比如打印机等 一般设备文件都存在/dev目录下 比如/dev/lp 就可能是一个打印机- 管道(pipe) 管道是一种用来连接2个进程的虚拟文件
比如下图如果进程A想要和进程B通信
首先要创建一个管道 然后进程A把数据输出到管道中 进程B在从管道中把数据读取出来 这样就完成了通信。
一个进程想要判断他输出的是普通文件还是管道需要一个特殊的系统调用 命令解释器 shell 他是终端用户和操作系统之间的 主要接口 shell分为2种
第一种是图形界面shell 如CDE GNOME KDE XFCE等
第二种是命令行shell 如果bash sh ksh csh等他们都来源最初的
sh
当用户登录系统(服务器)的时候 同时将启动一个shell
他以终端作为标准的输入输出 然后显示一个系统提示符 比如熟悉的美元 $ 符号 标识等待接受一条用户的命令
这时 比如用户输入了date 那么shell将会创建一个子进程来运行date程序 并等待子进程的运行结束。
当子进程运行结束后会再次显示系统提示符 等待用户输入。通过使用管道可以把一个程序的输出结果当作另外一个程序的输入。
比如: cat file1 file2 file3 | sort > /dev/lp 这条命令先调用cat程序把3个文件进行了合并
然后调用sort程序把合并结果传进来进行排序 然后把排序结果重定向到了/dev/lp 这正是打印机的设备文件另外还可以在一条命令的最后加上一个 “&” 符号表示不等待程序的执行结束直接显示系统提示符
可以直接执行别的程序 上一个带&没执行结束的程序将当作后台程序执行
系统调用的基本分类
大致分为下面几个分类的系统调用(每一个里面有很多的调用 先了解下!)
- 进程相关系统调用
- 信号相关系统调用
- 文件相关系统调用
- 文件系统相关系统调用
- 保护机制相关系统调用
- 时间相关系统调用
操作系统的结构[结构发展史]
- 整体结构 这个是最开始的设计
- 有一个主程序 用来调用被请求的服务例程
- 一组服务例程 用来实现相应的系统调用
- 一组工具函数 用来帮助服务例程的实现
- 分层结构 在上面整体结构上做了更加具体的分层 每一层都是在上一层的基础上扩展出来 不用管他上一层的实现
- 虚拟机
- 外核(ps:这个看的不是很懂 了解下好了)
- 客户端-服务器 这种就类似我们先的结构了
对于用户而言他不会关心请求发送到哪里的服务器 是在本地处理还是在某个地方服务器处理 他只要得到回复就可以了