操作系统介绍
操作系统介绍
在冯诺伊曼体系中,程序对机器码读取并执行,而在现代的操作系统设计中(意味着需要考虑到多程序同时运行),程序并不直接访问硬件(需要保护硬件资源),这时就需要一个软件来协调二者:通过受保护的方式分配资源给各个程序;这一软件就是操作系统,因此操作系统也可以看作硬件与应用程序间的抽象层。
操作系统这一抽象(abstraction)的设计原则也是计算机科学中的常用手法。本节开头引述的David Wheeler的这句名言超前地预言了计算机科学的现状。这句名言中的‘level of indirection’也会被故意错误地被引用为‘layer of abstraction’(后者的说法更接近当下流行的语言)。实际上,抽象使得构建一个更大型的系统更加容易,例如在使用高级语言编程的时候不用去关心下层的汇编、数字电路或者晶体管的细节;在网络栈中传输应用数据的时候不需考虑物理电缆是否可靠;在操作系统中运行程序的时候也不用去关心硬件资源的使用和保护。
该书提出操作系统的三大话题是:virtualization, concurrency 和 persistency;细分下来,分别对应了操作系统中的数个组件(或技术)。
虚拟化CPU
CPU虚拟化的技术目标就是产生一种存在无限多CPU的假象,这一目标主要通过时分共享(time sharing)实现。时分共享中的执行单位/调度单位就是进程。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "common.h"
int main(int argc, char *argv[]) {
if (argc != 2 ) {
fprintf(stderr,"usage: cpu <string>\n");
exit(1);
}
char * str = argv[1];
while (1){
Spin(1);
printf("%s\n", str);
}
return 0;
}
void Spin(int i) {
sleep(1);
}
运行结果
$ ./CpuVitruilzation.exe A & ./CpuVitruilzation.exe B & ./CpuVitruilzation.exe C & ./CpuVitruilzation.exe D
[1] 899
[2] 900
[3] 901
A
B
C
D
A
B
C
虚拟化内存
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <assert.h>
#include "common.h"
void Spin(int i);
int main(int argc, char *argv[]) {
int *p = malloc(sizeof(int));
assert(p != NULL);
printf("(%d) memory address of p: %08x\n", getpid(), p);
*p =0;
while (1){
Spin(1);
*p += 1;
printf("(%d) p: %d\n", getpid(), *p);
}
return 0;
}
void Spin(int i){
sleep(1);
}
结果
C:\Users\SuperNu1L\CLionProjects\CpuVitruilzation\cmake-build-debug\CpuVitruilzation.exe
(3496) memory address of p: 63ae1480
(3496) p: 1
(3496) p: 2
(3496) p: 3
(3496) p: 4
(3496) p: 5
(3496) p: 6
(3496) p: 7
(3496) p: 8
(3496) p: 9
(3496) p: 10
(3496) p: 11
(3496) p: 12
(3496) p: 13
(3496) p: 14
进程已结束,退出代码-1073741510 (0xC000013A: interrupted by Ctrl+C)
多线程
#include <stdio.h>
#include <stdlib.h>
#include "common.h"
volatile int counter = 0;
int loops;
void *worker(void *arg) {
int i;
for (i = 0; i < loops; i++) {
counter++;
}
return NULL;
}
int
main(int argc, char *argv[]) {
if (argc != 2) {
fprintf(stderr, "usage: threads <value>\n");
exit(1);
}
loops = atoi(argv[1]);
pthread_t p1, p2;
printf("Initial value : %d\n", counter);
Pthread_create(&p1, NULL, worker, NULL);
Pthread_create(&p2, NULL, worker, NULL);
Pthread_join(p1, NULL);
Pthread_join(p2, NULL);
printf("Final value : %d\n", counter);
return 0;
}
持久性
件以某种输入/输出(Input/Output,I/O)设备的形式出现。在现现系统中,硬盘驱动器(hard drive )是存储长期保存的信息的通用存储库,尽操固态硬盘(Solid-State Drive ,SSD)正在这个领域取得领先地位
#include <stdio.h>
#include <unistd.h>
#include <assert.h>
#include <fcntl.h>
#include <sys/types.h>
int
main(int argc, char *argv[])
{
int fd = open("/tmp/file", O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU);
assert(fd > -1);
int rc = write(fd, "hello world\n", 13);
assert(rc == 13);
close(fd);
return 0;
}
文件系统必须做很多工作:首先确定新数据将驻留在磁盘上的哪个位置,然后在文件系统所维护的各种结构中对其进行记录。这样做需要向底层存储设备发出 I/O 请求,以读取现有结构或更新(写入)它们。所有写过设备驱动程序①(device driver)的人都知道,让设备现表你执行某项操作是一个复杂而详细的过程。它需要深入了解低级别设备接口及其确切的语义。幸运的是,操作系统提供了一种通过系统调用来访问设备的标准和简单的方法。因此,OS 有时被视为标准库(standard library)。
三大话题 | 对应技术 - 抽象 | 技术目标 |
---|---|---|
虚拟化(virtualization) | CPU虚拟化- 进程 | 对每个程序提供“该系统拥有无限数量的CPU”的假象 |
虚拟化(virtualization) | 内存虚拟化 - 虚拟内存 | 对每个程序提供“该程序独占系统的所有内存空间”的假象 |
并发(concurrency) | 多线程并发 - 同步机制 | 让多个同时进行的程序以预期的顺序执行并得到预期的结果 |
持久性(persistency) | 单机数据持久 - 文件系统 | 保持存储的数据长期稳定安全 |
持久性(persistency) | 联机数据持久 - 分布式文件系统 | 使用不可靠的机器提供可靠的文件系统服务 |
抽象-机制-策略
抽象(abstraction)、机制(mechanism)、策略(policy)。
操作系统是一层提供接口给程序而隐藏了对硬件细节的抽象;而进程、虚拟内存、文件等这些概念则是对相应资源或者数据的抽象
机制则一般与策略成对出现,机制作为一个解决方案里的框架,相对模糊和广泛,而策略则规定了其中有限的细节,这种关系就像是应用程序与配置文件之间的关系。例如CPU调度是一种机制,具体使用哪种方法(如轮转调度、优先级调度等)则是策略;缓存替换是一种机制,而具体替换掉哪一个(例如LRU替换、随机替换等)则是策略。
- 0
- 0
- 0
- 0
- 0
- 0