操作系统-导论


操作系统

第一部分 虚拟化

第1章 操作系统介绍

1.虚拟化CPU

1.虚拟化:操作系统将物理资源(如处理器,内存,磁盘等)转化为更加强大的更加通用使用的虚拟形式,有时我们也将操作系统称为虚拟机或者是资源管理器。
2.什么是虚拟化CPU?
将单个CPU(或者是其中的一部分)转换为看似无限数量的CPU,从而让许多程序看似同时运行,这就是所谓的虚拟化CPU。

2.虚拟化内存

1.程序运行时,访问的指令来自于哪里?
程序将所有的数据结构保存在内存中,并通过各种指令来访问它们,程序的每个指令都在内存中,所以每次读取指令都会访问内存。
2.每个运行的程序都在相同的地址处分配了内存,但是打印出来的实际值却不一样呢?
这正是操作系统中虚拟化内存时发生的情况,每个进程都访问属于自己私有的虚拟地址空间,操作系统以某一种特有的方式映射到机器的物理地址上,实际上我们访问的实际物理地址是不一致的,它完全拥有属于自己的地址内存,物理内存是由操作系统管理的共享资源。在这段理解中,我们还可以理解进程是资源分配的最小单位,进程内存访问虚拟内存空间,进程相当于是一个中间层,通过映射关系对应到真实的物理内存空间。

3.并发

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;
}

我们可以将线程看作是与其他函数在同一内存空间中运行的函数,并且每次都有多个线程处于活动状态。
在这段代码中,main是主函数,两个子线程是worker,主线程和子线程在同一地址空间,起子线程和函数调用的区别就是,函数调用仍然在原逻辑执行流中,起子线程是新起了一个与原逻辑执行流并行的新线程,两个线程的执行是独立的(除了共享使用内存除外)
实际上当loops输入为1000的时候可能最终结果由两个线程得到的结果可能是2000,但如果数据持续增加,极大可能得到的数据几乎都是不一致的。
为什么会出现这种情况?
增加共享计数器的地方需要执行3条指令:一条将计数器的值从内存加载到寄存器,一条是将其递增,另一条是将其保存回内存,但这三条指令并不是以原子性执行,简而言之就是在没有锁的情况下,A线程在读取的过程中,B线程完成了数据的计数,那么A读取到的值就可能是一个假的值,那最终结果就会出错。

如何构建正确的并发程序?
1.如果一段内存空间中有很多并发执行线程,如何构建一个正确的工作程序?
2.操作系统需要什么原语?
3.硬件需要提供哪些机制?
4.如何利用它们来解决并发问题?

4.持久性

1.什么是DRAM?
DRAM是动态随机存取存储器,最为常见的系统内存,它只能将数据保持极短的时间,使用电容存储,需要一段时间就刷新,如果没有刷新存储信息就会丢失,例如关机。
2.操作系统中管理磁盘的软件通常称为文件系统。
3.磁盘文件和CPU关于虚拟化区别?操作系统不会为每个应用程序创建专用的虚拟盘。
CPU和内存是运行程序需要占用的资源,互相独立,使用虚拟化能够更加高效和易于管理,但磁盘文件是共享的资源,可能会被各种程序使用,不适合虚拟化,但可以做到权限控制。
** 如何持久地存储数据 **
1.如何将数据存储到硬盘?
2.如何才能高效实现?
3.出现故障,操作系统应该怎么办?
4.写缓冲的好处是什么?
现代处理器使用写缓冲区临时向内存写入地数据,写缓冲区可以保证指令流水线运行,避免由于处理器停顿下来等待向内存写入数据而产生地延迟,同时,通过以批处理地方式刷新写缓冲区,以及合并写缓冲区对同一内存地址的多次写,减少对内存总线地占用。

第2章 抽象:进程

虚拟化CPU来提供这种假象,通过让一个进程只运行一个时间片,然后再切换到其他进程,操作系统提供了存在许多虚拟化CPU的假象,这就是时分共享。

1.进程

操作系统为正在运行的程序提供抽象,就是所谓的进程。
什么是进程的机器状态:程序在运行时可以读取或更新的内容。指令在内存中,正在运行的程序读取和写入的数据也在内存中国,因此进程可以访问的内存(称为地址空间)是该进程的一部分,进程的机器状态另一部分就是寄存器。

2.进程API

1.销毁:因为存在创建进程的接口,因此还需要一个销毁的接口,虽然很多程序在运行完成后可以技术退出,但是可能存在失控的状态。
2.等待:有时等待进程停止运行是有用的,因此经常提供某种等待接口。
3.其他控制:除了杀死或等待进程外,有时还可能控制。过一段时间后继续恢复。
4.状态:有一些接口可以获得有关进程的状态信息。

3.进程创建:更多细节

操作系统第一件事就是将代码和所有的静态数据加载到内存中,加载到进程的地址空间。

加载之后,操作系统必须为程序的运行时栈分配一些内存,也有可能为程序的堆分配一些内存,举个例子,使用malloc函数申请的动态空间是堆区里面。
程序运行步骤:从磁盘加载程序的指令和数据->创建和初始化->I/O设置->跳转到程序入口(main函数)。

4.进程状态

进程的三种状态:
1.运行:在运行状态下,进程正在处理器上运行,这意味着它正在执行指令。
2.就绪:在就绪状态下,进程已经准备好运行,但由于某种原因,操作系统选择不在此时运行。
3.阻塞:在阻塞状态下,一个进程执行了某种操作,直到发生其他事件的时候才准备运行,举例,当进程像I/O请求时,它会阻塞,因此其他进程可以使用处理器。

首先:我们想象两个正在运行的进程,每个进程只是用CPU(它们没有I/O)

在下一个例子中,第一个进程在运行一段时间后发起I/O请求,此时该进程被阻塞,让另一个进程有机会。

第3章 插叙:进程API

首先,我们应该带着一个疑问,操作系统应该为进程创造和控制提供什么接口?如何设计这些接口才能既方便又实用呢࿱

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值