Operating Systems Design and Implementation Note

第二章 进程

2.1 进程介绍

2.1.5 进程的状态

调度器,决定哪个进程应当运行,以及它运行多长时间.

一些动作,诸如保存寄存器值和设置栈指针等无法用C语言描述,所以用一个短小的汇编语言例程来完成.

2.1.7 线程

它们共享相同的地址空间.

观察进程的一种方式是把进程视为一组相关资源的集合。

进程用来集合资源,而线程是CPU中调度的实体.

进程有进程表,线程有线程表.

2.2.2 临界区

避免竞争条件, 防止多个进程同时访问共享数据.

这里把对共享内存进行访问的程序片段称为 critical region 或 critical section.

TSL指令

Test and Lock,它将一个存储器字读到寄存器中,然后在该内存地址上存一个非零值. 该指令结束之前其他处理机构均不允许访问该存储器.

有忙等待的缺点.

通过TSL指令来确保同一时刻只有一个CPU在对信号量进行操作.

2.2.6 Mutex

互斥, Mutex.

是一个可以处于两态之一的变量: 解锁和加锁. 常用一个二进制位或整数表示.

加锁即非零,表示已被占用。

解锁为0.

死锁 dead lock
两个进程永远的阻塞.

2.2.7 管程

monitor, 管程,是由过程、变量及数据结构等组成的集合.

任意时刻管程中只能有一个活跃进程.

2.3 Classical IPC Problems

2.3.1 哲学家进餐问题

所有的程序都在运行,但却无法取得进展称 starvation 饥饿.

需保证既不会发生死锁又不会发生饥饿.

信号量的使用.

critical region 的运用.

2.3.2 读者-写者问题

2.4 Scheduling

Scheduler,调度器,在操作系统中决定先运行哪一个进程.

admission scheculer, 准入调度器,决定哪些作业允许进入系统.

三级调度: 准入调度器, CPU调度器, 内存调度器.

2.4.3 交互式系统中的调度

时间片论转调度 Round-Robin Scheduling

每个进程被分配一个时间片.

优先级调度 Priority Scheduling

每个进程被赋予一个优先级,率先运行优先级最高的就绪进程.

优先级可以为静态或动态.

2.4.4 实时系统调度 Scheduling in Real-Time Systems

通常分为: 硬实时和软实时.

2.5 MINIX 3 进程概述

汇编语言负责内核直接与硬件交互的最底层部分,这部分不能用C实现.

进程都潜在具有一定的特权,这是第二层、第三层和第四层内的进程真正的不同之处.

理解 kernel call 和 POSIX system call 的区别非常重要.

内核调用是由系统服务提供的以使驱动程序和服务器完成工作的底层函数.

POSIX系统调用是由POSIX规范定义的高层调用.

在init进程运行之前,就有一些系统进程已经运行了.

在类UNIX系统中,init被赋予的PID为1.

rc脚本的一个重要功能是检查可能由上次系统崩溃所引起的文件系统错误.

一个进程的所有信息都保存在进程表中,进程表划分成为内核、内存管理器和文件系统三部分, 分别拥有它们各自所需要的那些域.

2.5.3 MINIX 3 中的进程间通信

阻塞:正在执行的进程由于发生某事而暂时无法继续执行.

2.5.4 MINIX 3 中的进程调度

中断系统能使多道程序操作系统持续不断地工作,

任务通常有最高的优先级,驱动程序次之,服务器再次,最后是用户进程。

只有当所有的系统进程都无事可做时,用户进程才能运行。系统进程不会被用户进程阻止运行.

2.6 MINIX 3 中进程的实现

“过程”、“函数”、以及“例程”可以混用。

每一个C编译器都会到一个默认的头文件目录中去查找include文件,大多数情况下,这个目录是/usr/include/.

当一个include文件是在一个小于号和一个大于号之间<>被引用时,编译器则到默认头文件目录或者一个指定目录中去查找该文件.

""中是本地头文件.

src目录应该是source源代码目录.

通常情况下,操作系统中的三大块通用的程序只有/src/lib/目录中的库程序.

特性测试宏,feature test macro, 如

1
#define _ANSI

在编译一个C程序时,数据结构、参数以及函数返回值在引用它们的代码之前必须是已知的。因此C允许在定义之前使用函数原型来声明一个函数的参数和返回值.

在一次编译中,一个头文件应该仅被包含一次, 使用:```
#ifndef …

#endif

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
所有的类型名都以"_t"结尾,这不仅是一种习惯,而且是POSIX标准规定.

对于编译器,首字母大写的所有类型都等价于int类型.
### 2.6.4 MINIX 3 头文件
以下划线开头可以降低冲突的可能性.

对于磁盘的缓存来说,用于文件系统的缓存容量是越大越好.

声明被包含于两个以上的文件中,则有些链接程序将会把它认做变量多重定义错误.
### 2.6.6 引导MINIX 3
未分区磁盘,第一个扇区是引导块。

已分区磁盘,第一个扇区是主引导记录(含分区表),又称主引导程序. 通常有且只有一个分区被表示为活动状态.

一个MINIX分区与一个未分区的MINIX 3 软盘结构相同.

在装入操作系统之前无法通过目录和文件名来定位一个文件.

通常`#include`用来包含头文件, 但也可以用来选择源代码的适当部分.

#include <minix/config.h>
#if _WORD_SIZE == 2
#include “mpx88.s”
#else
#include “mpx386.s”
#endif


在C语言中`a[i]`只是`*(a+i)`的另一种写法.
## 3 Input/Output
操作系统的主要功能之一是控制所有的输入/输出设备.
### 3.1.1 I/O设备
大致分为两类:

 1. block device, 块设备
 2. character device, 字符设备

块设备将信息存储在固定大小的块中,每个块都有自己的地址。数据块的大小通常在512字节到32768字节之间。块设备的基本特征是每个块都能够独立于其他块而读写。磁盘是常用的块设备.

字符设备发送或接受的是字符流,而不考虑任何块结构。字符设备无法编址,也不存在任何寻址操作。打印机、网络接口、鼠标以及大多数与磁盘不同的设备均可被视为字符设备.

时钟的全部功能就是按照预先定义的时间间隔发出中断.

文件系统仅仅控制抽象的块设备,而把与设备无关的部分留给较底层软件,即设备驱动程序(device driver)去处理。

### 3.1.2 设备控制器
I/O设备通常由一个机械部件和一个电子部件组成。

电子部件称为 device controller,设备控制器或 adapter, 适配器. 

机械部件则是设备本身.

操作系统大多与控制器之间通信,而非设备本身.

preamble,前导符是磁盘格式化时写进去的,他包括柱面数和扇区数、扇区大小之类的数据,还包括同步信息。

在对检验和进行校验并证明数据快没有错误后,字节快将被复制到主存中.
### 3.1.3 内存映射I/O
每个控制器都有一些用来与CPU通信的寄存器。

除了这些控制寄存器之外,许多设备还有一个操作系统可以读写的数据缓冲区.

CPU与控制寄存器和设备的数据缓冲区进行通信的方法:

 1. 分配I/O端口号, 内存和I/O的地址空间是不同的
 2. 内存映射I/O, I/O寄存器是内存地址空间的一部分. 每个控制寄存器被分配唯一的一个内存地址,而且不会有内存分配这一地址. 通常分配给控制寄存器的地址位于地址空间的顶端.

### 3.1.4 中断 
p154

Operating Systems Design and Implementation Note
http://example.com/2022/07/15/Operating-Systems-Design-and-Implementation-Note/
作者
Jie
发布于
2022年7月15日
许可协议