现象
现象如图所示,会一直打印A。
在执行时,追踪IDT表,发现表中每一项第四位的值发生了变化。
在IDT表初始化后,其所有描述表的第四位的值均为ignore_int首第四位值,即0x114。
在修改的程序后,每次eax都会多执行一条+2的指令。
关键代码如下
1 |
|
我们修改的字符为19个,再加上前后一共3个回车加换行,所以总共25个字符。
将 .org 508 修改为 .org 510,是因为这里不需要 root_dev: .word ROOT_DEV,为了保证 boot_flag 一定在最后两个字节,所以要修改 .org。
执行下面两个命令编译和链接 bootsect.s
1 | $ as86 -0 -a -o bootsect.o bootsect.s |
需要留意的文件是 bootsect
的文件大小是 544
字节,而引导程序必须要正好占用一个磁盘扇区,即 512
个字节。 造成多了 32
个字节的原因是 ld86
产生的是 Minix
可执行文件格式, 这样的可执行文件处理文本段、数据段等部分以外,还包括一个 Minix
可执行文件头部。
去掉32字节的头部文件。
1 | dd bs=1 if=bootsect of=Image skip=32 |
接下来进行拷贝,并且run
1 | # 当前的工作路径为 /common/linux-0.11/boot/ |
注:由于我执行run的时候有些许问题,所以我对于目录结构进行了修改。
效果如下图
首先编写一个 setup.s,该 setup.s 可以就直接拷贝前面的 bootsect.s,然后将其中的显示的信息改为:“Now we are in SETUP”。
1 | entry _start |
接下来需要编写 bootsect.s
中载入 setup.s
的关键代码,注意去掉无限循环
1 | SETUPLEN=2 ! 读入的扇区数 |
效果如下图
需要修改build.c,并且删除同目录下的 hdc-0.11.img.lock
即可。
setup.s
将获得硬件参数放在内存的 0x90000
处。原版 setup.s
中已经完成了光标位置、内存大小、显存大小、显卡参数、第一和第二硬盘参数的保存。
用 ah=#0x03
调用 0x10
中断可以读出光标的位置,用 ah=#0x88
调用 0x15
中断可以读出内存的大小。 有些硬件参数的获取要稍微复杂一些,如磁盘参数表。在 PC
机中 BIOS
设定的中断向量表中 int 0x41
的中断向量位置( 4*0x41 = 0x0000:0x0104
)存放的并不是中断程序的地址,而是第一个硬盘的基本参数表。 第二个硬盘的基本参数表入口地址存于 int 0x46
中断向量位置处。每个硬盘参数表有 16
个字节大小。
在PC机中BIOS设定的中断向量表中int 0x41的中断向量位置存放的并不是中断程序的地址,而是第一个硬盘的基本参数表。对于100%兼容的BIOS来说,这里存放着硬盘参数表阵列的首地址0xF000:0E401,第二个硬盘的基本参数表入口地址存于int 0x46中断向量位置处.每个硬盘参数表有16个字节大小.
这段话是重点,磁盘参数就存放在以0x0000:0x0104为首地址的单元中只存了4个字节,里面存放的是磁盘参数表的偏移地址和段地址,也就是上文所说这里存放着硬盘参数表阵列的首地址0xF000:0E401。
以十六进制方式显示比较简单。这是因为十六进制与二进制有很好的对应关系(每 4 位二进制数和 1 位十六进制数存在一一对应关系),显示时只需将原二进制数每 4 位划成一组,按组求对应的 ASCII 码送显示器即可。ASCII 码与十六进制数字的对应关系为:0x30 ~ 0x39 对应数字 0 ~ 9,0x41 ~ 0x46 对应数字 a ~ f。从数字 9 到 a,其 ASCII 码间隔了 7h,这一点在转换时要特别注意。为使一个十六进制数能按高位到低位依次显示,实际编程中,需对 bx 中的数每次循环左移一组(4 位二进制),然后屏蔽掉当前高 12 位,对当前余下的 4 位(即 1 位十六进制数)求其 ASCII 码,要判断它是 0 ~ 9 还是 a ~ f,是前者则加 0x30 得对应的 ASCII 码,后者则要加 0x37 才行,最后送显示器输出。以上步骤重复 4 次,就可以完成 bx 中数以 4 位十六进制的形式显示出来。
如下图:
代码如下
1 | ! 文件setup.s |
1 | 当PC的电源打开后,80x86结构的CPU将自动进入实模式,并从地址0xFFFF0开始自动执行程序代码,这个地址通常是ROM—BIOS中的地址。PC机的BIOS将执行某些系统的检测,并在物理地址0处开始初始化中断向量。此后将启动设备的第一个扇区512字节读入内存绝对地址0x7C00处。因为当时system模块的长度不会超过0x80000字节大小512KB,所以bootsect程序把system模块读入物理地址0x10000开始位置处时并不会覆盖在0x90000处开始的bootsect和setup模块,多此一举的是system模块移到内存中相对靠后的位置,以便加载系统主模块。解决方案是在保证操作系统启动引导成功的前提下尽量扩大ROM—BIOS的内存寻址范围。 |
AH&AL=AX(accumulator):累加寄存器,常用于运算;在乘除等指令中指定用来存放操作数,另外,所有的I/O指令都使用这一寄存器与外界设备传送数据。
BH&BL=BX(base):基址寄存器,常用于地址索引
CH&CL=CX(count):计数寄存器,常用于计数;常用于保存计算值,如在移位指令,循环(loop)和串处理指令中用作隐含的计数器.
DH&DL=DX(data):数据寄存器,常用于数据传递。
他们的特点是,这4个16位的寄存器可以分为高8位: AH, BH, CH, DH.以及低八位:AL,BL,CL,DL。这2组8位寄存器可以分别寻址,并单独使用。
注意,这里ah要先有值,代表内部子程序的编号
功能号ah=0x03,作用是读取光标的位置
输入:
1 | bh = 页号 |
返回:
1 | ch = 扫描开始线;cl = 扫描结束线;dh = 行号;dl = 列号 |
功能号ah=0x13,作用是显示字符串
输入:
1 | al = 放置光标的方式及规定属性,下文 al=1,表示目标字符串仅仅包含字符,属性在BL中包含,光标停在字符串结尾处;es:bp = 字符串起始位置;cx = 显示的字符串字符数;bh = 页号;bl = 字符属性,下文 bl = 07H,表示正常的黑底白字;dh = 行号;dl = 列号 |
功能号ah=0x0e,作用是显示字符
输入:
1 | al = 字符 |
在DOS等实模式操作系统下,调用INT 13h会跳转到计算机的ROM-BIOS代码中进行低级磁盘服务,对程序进行基于物理扇区的磁盘读写操作。
功能号ah=0x02,作用是读磁盘扇区到内存
输入:
寄存器 | 含义 |
---|---|
ah | 读磁盘扇区到内存 |
al | 需要读出的扇区数量 |
ch | 磁道 |
cl | 扇区 |
dh | 磁头 |
dl | 驱动器 |
es:bx | 数据缓冲区的地址 |
返回
1 | ah = 出错码(00H表示无错,01H表示非法命令,02H表示地址目标未发现…);CF为进位标志位,如果没有出错CF=0 |
功能号ah=0x00,作用是磁盘系统复位
1 | 输入:dl = 驱动器 |
功能号ah=0x88,作用是获取系统所含扩展内存大小
1 | 输入:ah = 0x88 |
在PC机中BIOS设定的中断向量表中int 0x41的中断向量位置 (4 ∗ 0 x 41 = 0 x 0000 : 0 x 0104 4*0x41 = 0x0000:0x01044∗0x41=0x0000:0x0104)存放的并不是中断程序的地址,而是第一个硬盘的基本参数表。对于100%兼容的BIOS来说,这里存放着硬盘参数表阵列的首地址0xF000:0E401,第二个硬盘的基本参数表入口地址存于int 0x46中断向量位置处.每个硬盘参数表有16个字节大小.
格式: LDS reg16,mem32
其意义是同时给一个段寄存器和一个16位通用寄存器同时赋值
举例:
地址 | 100H | 101H | 102H | 103H |
---|---|---|---|---|
内容 | 00H | 41H | 02H | 03H |
1 | LDS AX,[100H] |
执行前栈的内容
执行后栈的内容
在执行前后进行了栈的切换,从任务0的内核栈切换到了任务的用户栈。
当进入和退出 system_interrupt
时,都发生了模式切换,请总结模式切换时,特权级是如何改变的?栈切换吗?如何进行切换的?
在进入中断时,通过查询IDT表,获得索引,之后进行特权级检查,要求CPL<=调用门DPL;RPL<=调用门DPL。DPL<=CPL。特权级检查通过,则特权级改变。栈也进行切换。处理器从当前任务的TSS段获得该中断使用的堆栈的段选择符与栈指针,然后把被中断的栈选择符与栈指针压入新栈。EFLAGES、CS、EIP的值也被压栈。
当退出时,使用iret指令。把保存的寄存器内容恢复到EFLAGES中,完成特权级复原,即切换为3。同时栈也切换回原来的栈。
当时钟中断发生,进入到 timer_interrupt
程序,请详细记录从任务 0
切换到任务 1
的过程。
以本图为例分析。说明第一次切换时的状况,第一次切换,即时钟中断发生时,大概率会在227行,此时任务号为0,当跳入时钟中断后,从125行开始进行转换,首先将1写入寄存器eax,然后判断,因为此时任务号为0,所以不执行127行,执行128行,则将任务号改为1,然后在129行跳转到任务1的代码段。
任务0时的寄存器如下:
任务1时的寄存器如下:
又过了 10ms
,从任务1切换回到任务 0
,整个流程是怎样的? TSS
是如何变化的?各个寄存器的值是如何变化的?
如图,承接上题叙述,从代码段228执行,在232循环,大概率在循环时进行时间中断发生,在126行比较时,由于此时任务号为1,所以跳转到131行,将任务号设为0,在132行处,跳转到任务0,由于任务0执行到129行,所以从130执行,再跳转到133行,弹栈后通过iret返回,由于上次为在226行触发中断,所以回到226行。
寄存器变化如下:
变至
下图为任务0的TSS
下图为任务1的TSS
还是对照这张图片,从头来讲。
第一次切换,即时钟中断发生时,大概率会在227行,此时任务号为0,当跳入时钟中断后,从125行开始进行转换,首先将1写入寄存器eax,然后判断,因为此时任务号为0,所以不执行127行,执行128行,则将任务号改为1,然后在129行跳转到任务1的代码段。
从代码段228执行,在232循环,大概率在循环时进行时间中断发生,在126行比较时,由于此时任务号为1,所以跳转到131行,将任务号设为0,在132行处,跳转到任务0,由于任务0执行到129行,所以从130执行,再跳转到133行,弹栈后通过iret返回,由于上次为在226行触发中断,所以回到226行。
然后大概率在此行,再次遇到时间中断,从125行开始进行转换,首先将1写入寄存器eax,然后判断,因为此时任务号为0,所以不执行127行,执行128行,则将任务号改为1,然后在129行跳转到任务1。由于任务1上次执行至
132行,所以从133行开始,到iret返回至232行。
又大概率在232行遇到时钟中断,执行到126行比较后跳转到131行,将任务号变为0,回到任务0的代码段。
至此为一个流程。
主要包括初始设置与任务执行切换。
初始设置包括:
1.设置GDT表。
2.设置系统定时芯片。
3.设置IDT表。
4.切换到任务0。
任务执行切换则为:
head.s程序中把定时器芯片8253的通道0设置成每经过10ms就向中断控制芯片8259A发送一个时钟中断请求信号。PC机的ROM BIOS开机时已经在8259A把时钟中断请求信号设置成中断向量8,在中断8的处理过程中执行任务切换操作。任务切换的实现方法是查看current变量中当前运行任务号,若当前为0,就利用任务1的TSS选择符作为操作数执行远跳转指令,从而切换到任务1中执行,否则反之。
每个任务在执行时,会先把一个字符的ASCLL码放入寄存器AL中,然后调用系统中断调用int 0x80,而该系统调用处理过程则会调用一个简单的字符写屏子程序,把寄存器AL中的字符显示在屏幕上,同时把字符显示的屏幕下一个位置记录下来,作为下一次显示字符的屏幕位置。在显示过一个字符后,任务代码会使用循环语句延迟一段时间,然后跳转到任务代码开始出继续循环执行,从而不断显示。
首先从GDT表看起,GDTR为0x998(3f),则跳转到0x998去。寄存器SS的内容为0010。
由于第一项为空,则从第二项看,第二项为FF 07 00 00 00 9A C0 00。将其填写到段描述中,发现其S为1,TYPE为A,为代码段,G为1,段限长为0 07 FF ,基地址为0。则实际段长度为8MB。
第三项为FF 07 00 00 00 93 C0 00。将其填写到段描述中,发现其S为1,TYPE为3,为栈段,G为1,段限长为0 07 FF ,基地址为0,B/D为1。
第四项为02 00 00 80 0B 92 C0 00,将其填写到段描述符中,发现其S为1,TYPE为2,为数据段,G为1,段限长为0 00 02,基地址为0XB8000。则实际段长度为8KB。
第五、第六、七项S为0。
再查询任务0 LDT表
同理分析,则代码段与数据段基地址均为0,段限长为0x03ff,实际长度为4MB。
再查询任务1 LDT表
同理分析,则代码段与数据段基地址均为0,段限长为0x03ff,实际长度为4MB。
再运行到任务0处,此时SS寄存器为0x17,栈段基地址为0,段限长为0x03ff。
运行到任务1同理,此时SS寄存器为0x17,栈段基地址为0,段限长为0x03ff。
初始化的代码段起始地址为0,段长为8MB,则终止地址为0X800000。数据段起始地址为0XB8000,段长为8kb,终止地址为0XBA000。
任务0的代码段起始地址为0,段长为4MB,则终止地址为0X400000。数据段起始地址为0,段长为4MB,则终止地址为0X400000。
任务1的代码段起始地址为0,段长为4MB,则终止地址为0X400000。数据段起始地址为0,段长为4MB,则终止地址为0X400000。
栈段编号 | 名称 | 起始地址 | 终止地址 |
---|---|---|---|
1 | init_stack | 0x9d8 | 0xbd8 |
2 | Km_stk0 | 0xc60 | 0xe60 |
3 | Km_stk1 | 0xe00 | 0x10e0 |
4 | User _stk1 | 0x1108 | 0x1308 |
将新调度任务(任务0)的上下文,加载进处理器中,并将从加载的EIP指向的指令出开始执行。具体操作为
57:将任务0当前局部空间数据段选择符入栈,
58:将堆栈指针入栈,
59:将标志寄存器值入栈,
60:将当前局部空间代码段选择符入栈,
61:将代码指针入栈,
62:通过执行中断返回指令,切换到特权级3的任务0执行。·
在iret执行前,eip的值为000000ac,esp为00000bc4,cs的值为0008,栈顶的值为000010e0,然后执行iret。
栈内五条内容均被弹出,其中000010e0被写入eip,同时0000000f被写入cs,则获得了下一条指令的地址。
执行前
执行后
看上述两张图,图一为执行时,ss为0010,esp为00000bc4,当iret执行后,会弹出五条内容。分别为之前保存的寄存器eip的值,寄存器cs的值,标志寄存器eflags的值,寄存器esp的值,寄存器ss的值。
调用int 0x80前,栈为task0或task1的用户栈
调用int 0x80后,为此任务的系统栈。
由于执行前任务特权级为3,而执行后任务特权级为0,所以进行了栈切换。压入了中断前的ss、栈指针、标志寄存器、cs和下一条指令的eip。ss寄存器的值也发生了相应变化。
用两个模型来预测,再用三组数据比较分析。
同时为了避免大环境的干扰,应对未试点的省份也进行预测。同时证明模型的合理性。
整体思路:
上海实施试点是2014年,所以我们采取14-19年作为政策采取后的数据,采用08-13作为政策采取前的数据。
通过08-13年的数据,采用合成控制法与..模型两种方式,预测分析政策未被实施的情况下上海地区的碳排放量,
模型中需要注意:
由于碳排放量所受的影响因素是多方面的,基于控制变量的原则,我们采用合成控制法预测上海地区的碳排放量时,所选择的其他地区应是未被试点的地区,同时我们假设,国家各地区整体的经济发展趋势大致拟合经济发展曲线,可消除一部分经济等其他因素对于实验数据的干扰。对于..模型,我们同样假设经济发展拟合经济发展曲线。通过这两种方式,我们可扩大我们所研究的试点政策对于碳排放量的影响。
为了验证我们预测模型的正确性,我们进行了稳健性检验,平行趋势检验,异质性分析。
稳健性检验:对于未试点的地区,同样用该模型进行预测,对预测数据与实际数据比较,发现拟合度较高,验证模型基本正确。
平行趋势检验:对于上海地区与选择的其他地区,在试点政策颁布前,有关碳排放政策大致相同。同时碳排放曲线大致相同。
异质性检验:
最后,对于模拟产生的两组数据,与实际数据,我们通过..分析法,对于三组数据进行分析,得出…
在之前的基础上进行改进,优化了数据结构和存储设计,改进了索引结构,满足第四范式。
1 | create database CMIS |
创建学生信息表
1 | create table 学生信息 |
创建教师信息表
1 | --创建教师信息表 |
创建院系信息表
1 | --创建院系信息表 |
创建教室信息表
1 | --创建教室信息表 |
创建教学楼信息表
1 | --创建教学楼信息表 |
创建课程信息表
1 | --创建课程信息表 |
创建教室使用信息表
1 | --创建教室使用信息表 |
创建课程时间表
1 | --创建课程时间表 |
设置主键
1 | --将教师信息表中教师编号设置为主键约束,身份证号设为唯一约束 |
设置外键约束
1 | --将教师信息中的院系号与院系信息中的院系号添加外键 |
设置检查约束
1 | --对教师信息中的性别添加约束 |
插入教学楼基本信息
1 | insert into 教学楼信息 |
插入教室基本信息
1 | insert into 教室信息 |
1 | insert into 教室信息 |
1 | insert into 教室信息 |
插入院系信息
1 | insert into 院系信息 |
插入教师信息
1 | insert into 教师信息 |
插入课程信息
1 | insert into 课程信息 |
插入课程时间
1 | insert into 教室使用信息 |
插入课程信息存储
1 | create procedure information_entry |
查询指定教室使用情况
1 | create procedure classroom_query |
少一个查询指定课程
借用存储
1 | declare @state varchar(10) |
一个例子
1 | select *from 教室使用信息 |
判断密码是否正确
1 | create procedure password_query |
删除课程
1 | create procedure delete_course |
删除教师
1 | create procedure delete_teacher |
创建存储往学生信息插入大量数据
1 | --创建循环插入10000条记录的存储过程 |
创建视图,查询计算机学院邹老师所有课程名称
1 | --创建视图,查询计算机学院邹老师所有课程名称 |
特点
1 | 数据存储于文件中 |
缺点
1 | 每当文件格式发生变化,就要修改应用程序 |
特点
1 | 数据存储在数据库中 |
(1)FS:每当文件格式发生变化,就要修改应用程序
DBMS:只要数据模式不发生重大变化,应用程序基本无需修改
(2)FS:文件中存在冗余数
DBMS:冗余数据较少
(3)FS:文件修改可能造成数据不一致
DBMS:在数据库规范情况下基本不会造成
(4)FS:文件修改可能会破坏数据正确性
DBMS:会对数据更新进行完整行进检查
(5)FS:没有索引,访问效率低
DBMS:提供索引
(6)FS:只能对整个文件进行访问控制,数据安全性差
DBMS:可规定用户对于数据库哪一部分进行操作
(7)FS:文4没有并发控制
DBMS:提供并发控制机制
数据库:有组织的、共享的、持久存储的数据集合。
由数据库、数据库管理系统、应用程序和数据库用户在一起构成的系统。
数据库模式通常分三个层次定义,从低到高分别是:
内模式/存储模式
概念模式
外模式/视图
描述数据库的物理存储结构和存取方式
数据库只有一个内模式
定义内模式时通常使用物理数据模型提供的概念
为全体数据库用户描述整个数据库的结构和约束
数据库只有一个概念模式
定义概念模式时使用实现数据模型提供的概念
从不同类别用户的视角描述数据库结构
可以有多个外模式
定义外模式时也可以使用实现数据模型提供的概念
在三层模式结构中,不同层次模式之间的映射用于完成应用程序与数据库之间的数据转换和请求转换。
分类
外模式-概念模式映射
概念模式-内模式映射
逻辑数据独立性
物理数据独立性
数据定义语言
数据操作语言
由数据库上的一系列操作完成的复杂任务,这些操作要么全执行,要么全不执行
性质
1 | 原子性 |
为了充分利用,允许多个事务并发执行。
多个事务并发可能会破坏数据一致性。
三要素:关系数据结构、关系操作、关系完整性约束。
关系中属性的个数即为关系的度。
只有符合客观实际的关系才是正确的关系。
键:关系的某些属性集合具有区分不同元组的作用。
超键:可以唯一标识每个元组的属性。
候选键:任意真子集都不是超键的超键。即极小的超键。
主键:每个关系都有至少一个候选键,人为指定其中一个作为主键。
外键:设F为关系R的属性子集。若F与关系S的主键K相对,则称F为R的外键。
查询语言的类型:关系代数、关系演算、结构化查询语言SQL。
完整性约束的类型:实体完整性、参照完整性、用户定义完整性。
实体完整性约束规则
1 | 主键值唯一且非空。 |
参照完整性约束
1 | 对于外键的约束,外键值为空或不为空则必须在S存在。 |
用户定义完整性约束
1 | 根据需求定义。 |
笛卡尔积作用仅仅是将R和S无条件连接起来。
等值连接:连接条件仅涉及相等比较的连接称作等值连接。
自然连接与$\theta$连接的区别
自然连接 | $\theta$连接 | |
---|---|---|
连接条件 | 隐含给出 | 明确给出 |
结果属性 | 去掉重复的同名属性 | 保留重名的同名属性 |
eg:
eg:
eg:
声明用户定义完整性约束
1 | 规定属性值非空 |
定义视图
从用户视角所看到的数据
修改:update 关系名 set
数据完整性检查
1 | 目的:数据修改可能导致数据库违反完整性约束,需要对数据完整性进行检查 |
选择查询条件
注意:空值判断,应用 is null,不可以用 =或者!=
集合操作
查询结果排序
限制查询结果数量
聚集查询
注:聚集函数不能出现在where子句中
分组查询
注意事项
内连接
自然连接
自连接
外连接
使用exists关键字进行查询的时候,首先,我们先查询的不是子查询的内容,而是查我们的主查询的表,然后,根据表的每一条记录,依次去判断where后面的条件是否成立。
in在查询的时候,首先查询子查询的表,然后将内表和外表做一个笛卡尔积,然后按照条件进行筛选。所以相对内表比较小的时候,in的速度较快。
嵌套查询的写法
派生
实体-联系模型:简称ER模型,用于将现实世界抽象为实体及实体间的联系。
ER模型概念:
实体:数据库中表示的现实世界中的具体对象或事物。
属性:用于刻画实体的特性。
属性的类型
1 | 简单属性 |
弱实体型:没有键属性的实体型。
标识实体型、属主实体型:由于弱实体型没有键属性,需要依赖于其他实体型进行区分。
标识联系型:弱实体型与其标识实体型通过标识联系型关联。
部分键:用于区分和同一标识实体相关联的弱实体的属性集合。
联系:一个联系表示多个实体之间有意义的关联关系。
联系型:同一类联系共同具有的类型。
联系型的度:参与到一个联系型中的实体型的个数。
联系集:数据库中当前存储的联系型的实例的集合。
存在依赖约束/参与度约束:刻画实体型参与到联系型中的最小基数。
多元联系:3个以上实体参与的联系
不相交子类:若超类的每个实体属于最多一个子类,则子类是不相交的。
重叠子类:若超类的每个实体可以属于多个子类,则子类是重叠的。
全部特化:超类的每个实体必须属于至少一个子类。
部分特化;超类的某些实体可以不属于任何子类。
实体型的转换
复合属性的转换
多值属性的转换
弱实体型的转换
M:N二元联系型的转换
N:1二元联系型的转换
1:1二元联系型的转换
与N:1相同
二元自联系型的转换
标识联系型的转换
设计不合理的关系可能产生的异常问题
1 | 数据更新问题 |
知识要点图
定义
类型
逻辑蕴含
相关概念
最小覆盖
若关系模式R的每个属性都是不可分的,则称R为第一范式关系模式。
存在问题
1 | 数据插入异常 |
原因
1 | 非主属性部分函数依赖于候选键 |
存在问题
1 | 数据插入异常 |
原因
1 | 非主属性传递函数依赖于候选键 |
存在问题
1 | 数据插入异常 |
原因
1 | 主属性部分依赖于候选键 |
消除主属性间的传递依赖。
分解准则1:无损连接性
分解准则2:函数依赖保持性
无损连接性判定
函数依赖保持性判定
1 | 在逻辑数据库设计的基础上,为数据库中的关系选择合适的存储结构和存取方法,并进行数据库调优,使数据库上的事务能够高效执行。 |
工作负载是一组混合在一起的查询和更新。
选择度:满足条件的结果元组在全部候选元组中所占的比例。
索引设计的基本过程
1.是否建索引
2.索引键的确定
3.复合索引的设计
B+树支持的查询
全值匹配:和所有索引属性进行匹配
匹配最左前缀:和前面几个索引属性进行匹配
匹配属性前缀:只匹配前缀属性的前缀部分
范围匹配:在给定范围内对前缀进行匹配
精确匹配某一属性并范围匹配另一属性
B+树还支持索引属性排序
B+树的限制
必须从B+树的最左属性开始匹配
条件中不能包含表达式
不能跳过B+树的属性
如果索引中有关某个属性的范围查询,则其右边所有属性都无法使用索引查找
覆盖索引
如果一个索引包含一个查询需要用到的所有属性,则称该索引为覆盖索引
单个复合索引 vs 多个单属性索引
方案一:建立一个符合索引
方案二:建立多个单属性索引
多个单属性索引的缺点
1 | 没有在单个复合索引上做查询效率高 |
4.是否使用聚簇索引
不同存取路径区别
5.用哈希表还是B+树
哈希表的限制
1 | 不支持部分索引属性匹配 |
6.权衡索引代价维护
7.不唯准则
MYSQL索引设计技巧1:前缀索引
索引选择性:
MYSQL索引设计技巧2:聚簇索引
MYSQL索引设计技巧3:伪哈希索引
关系是否采用聚簇索引?
若使用聚簇索引,应按哪些属性聚簇索引?
同聚簇索引设计准则。
恒真/假的选择条件
含表达式的选择条件
无用的去重操作
无用的分组操作:分组操作昂贵
无用的投影操作
无用的连接操作
临时关系:占用额外存储空间,且其上没有索引
嵌套查询;查询器优化嵌套查询能力弱
类型转换
数据类型选择
1 | 1.尽量使用可以正确存储的最小数据类型 |
标识符的选择
1 | 整型:最好的选择,占用空间少,速度快 |
按CPU访问存储介质的方式,可将存储器分为三类。
1 | 主存储器 |
主存
1 | 包括:寄存器、高速缓存、内存 |
二级存储器
1 | 包括:磁盘/机械硬盘、闪存/固态硬盘 |
三级存储器
1 | 包括:磁带、光盘、网络存储 |
存储层次间的数据传输
数据局部性:同一单元的数据经常被同时访问到
虚拟内存不是存储层级中的一层。
按存储介质的易失性/持久性,可分为
1 | 易失性存储器:计算机重启后,易失性存储器的数据会丢失 |
持久性内存又称非易失性内存:按字节寻址、非易失
磁盘
将一个数据库存储为一个或多个文件;每个文件包含多个页。
数据库文件的页可以存储元组、元数据、索引、日志记录等。
1 | 大多数DBMS在一个页中只存储一种类型对象。 |
每个页拥有唯一编号,称作页号。
DBMS的存储管理器负责管理数据库文件
1 | 记录页中元组的读/写 |
文件存储的分类
1 | 面向行的存储 |
数
字符串
元组
元组头
元组数据
变长元组的布局
页布局
页头
页数据
面向元组的组织方法
分槽页是最常见的面向元组的数据组织方法
1 | 槽数据 |
槽的元数据存储在页头中
1 | 槽的数量:用于确定下一个空闲槽的编号 |
记录号
溢出页
页碎片化
1 | 随着元组删除或版本过期,其中会产生碎片:浪费磁盘空间、增加磁盘I/O |
日志结构页布局
1 | 文件中只存储数据更新操作的日志记录,而不存储元组 |
1 | 新的日志记录只能写到文件末尾 |
读元组
日志记录索引
日志记录合并
法一:堆文件组织
法二:顺序/有序文件组织
法三:哈希文件组织
堆文件组织
基于链表的页组织方式
基于页目录的堆文件页组织方式
顺序/有序文件组织
哈希文件组织
缓冲池的页称作页框
页表
DBMS用两个变量记录缓冲池中每个页框的状态
缓冲区功能
1 | 请求页;修改页;释放页 |
请求页
1.
2.
3.
实际在情况3下,DBMS会终止提出该请求的事务,为了避免资源浪费
页替换策略
缓冲池与虚拟内存的相同点
缓冲池与虚拟内存的不同点
1.
2.
面向行的存储
面向列的存储
缺点:面向列的存储适合于联机分析处理,不适合于联机事务处理。元组重构代价高,元组删除和修改代价高;解压代价
有序索引:通过按索引键有序排列索引项来实现索引
哈希索引:通过按索引键哈希值分桶来实现索引
有序索引
哈希索引
根据数据文件中的元组是否按索引键值排序,分为聚簇索引与非聚簇索引。
聚簇索引
文件中的元组按索引键排序的,则索引为聚簇索引。
1 | 聚簇索引的索引键通常为关系主键; |
非聚簇索引
文件中的元组不按索引键排序的,则索引为非聚簇索引。
1 | 一个关系上可以有多个非聚簇索引 |
索引组织表
索引组织表=聚簇索引文件+数据文件
1 | 在索引组织表中,聚簇索引的索引项中存储元组本身,而不是地址 |
根据关系中每个元组在索引中是否都有一个对应索引项,可将有序索引分为两类:稠密索引、稀疏索引
稠密索引
稀疏索引
根据索引键是否为关系的主键,可将有序索引分为两类:主索引,二级索引
主索引
1 | 索引键为主键;一个关系只有一个 |
二级索引
1 | 索引键不是主键: |
创建主索引:
创建二级索引:
唯一索引:索引键值不能重复
外键索引
有序索引结构
1 | 平衡树 |
哈希索引数据结构
1 | 哈希表 |
外存哈希表
外存哈希表分类
插入
删除
二者对比
B+树插入、删除,看教程,此处不详细说明。
B+树演示
1 | https://cmudb.io/btree |
键压缩
前缀压缩
后缀截断
批量加载
B+树的原地更新
日志结构合并树
LSM树的基本结构
LSM的查找
缺点:当不可变文件非常大时,在文件上查找效率很慢
LSM的更新
分层LSM
位图索引
空间索引
查询处理的基本过程
原语操作:带有如何执行注释的关系代数操作。
查询执行计划:用于执行一个查询的原语操作序列
按照排序键对元组进行排序是DBMS非常重要的操作。
外排序
第一阶段:创建归并段
第二阶段:归并
记法
创建归并段
演示看PPT
算法分析
优化
双缓冲
1 | 1.基于扫描的选择算法 |
记法
前提
前提
1 | 1.一趟去重算法 |
可在内存中用哈希表记录见过的元组,哈希键为整个元组。
与去重一样
基于块的嵌套循环连接
迭代器模型
查询优化:将一个关系代数表达式转换成一个可以快速执行的查询执行计划的过程。
查询优化的两个阶段:
1 | 逻辑查询优化; |
逻辑查询计划:关系代数表达式
物理查询计划:带有“如何执行”注释的关系代数表达式
代价
基于代价的查询优化
若两个关系代数式在任意数据库实例上的结果都相同,则这两个关系代数表达式等价。
关系代数表达式的等价变换规则
$\theta$连接满足交换律,但不满足结合律。
逻辑查询计划的代价模型 VS 物理查询计划的代价模型
基数估计
基数估计:估计查询结果的元组数
要求:准确;易计算;逻辑一致
逻辑一致性
1 | 单调性:一个操作的输入越大,操作结果的基数估计值越大 |
笛卡尔积操作的基数估计
投影操作数的基数估计
选择操作的基数估计
二路自然连接的基数估计
集合操作的基数估计
去重操作的基数估计
实际数据经常不满足均匀分布假设,导致基数估计的误差较大
直方图
等宽直方图
等高直方图
压缩直方图
连接关系的角色
连接树
左深连接树
索引扫描+过滤
多索引扫描+求交集
仅用索引
顺序扫描
一趟连接:适用于左关系可以全部读入缓冲池的可用页面。
索引连接:适用于左关系较小,右关系在连接属性上建有索引
排序归并连接:
哈希连接:
嵌套循环连接:
事务的ACID性质
持久性
一致性
隔离性
调度:调度是一个或多个事务的重要操作的序列。
串行调度:如果一个调度中不同事务的操作没有交叉,则该调度是串行调度
调度的正确性:单独执行每个事务都会将数据库从一种一致状态变为另一种一致状态
串行调度的正确性:任意串行调度都能保持数据库的一致性;不同的串行调度可能导致数据库处于不同的状态,但都是一致状态
异常
脏写
脏读
不可重复读
等价调度
可串行化调度
可串行化调度的优点
可串行化调度的缺点
在不同隔离级别下,一个事务修改过的对象的值对其他并发事务的可见程度不同
读未提交
未提交事务所做的修改对其他事务可见。
此级别下的异常
读提交
只有已提交的事务所做的修改才对其他事物可见。
此级别下的异常
可重复读
此级别下的异常
可串行化
冲突可串行化
冲突
冲突等价
冲突可串行化调度
冲突可串行化测试
视图可串行化比冲突可串行化松
并发控制协议分类
基于锁的并发控制
两阶段锁协议
基于2PL的调度是冲突可串行化调度
2PL的优缺点
级联终止
强两阶段锁SS2PL
严格调度
死锁
死锁处理
死锁检测
等待图
死锁解除
死锁预防
锁的效率问题
锁的粒度
意向锁
相容矩阵
多粒度锁协议
锁升级
动态数据库
幻读
谓词锁
next- key锁
Basic TO
Thomas写规则
不可恢复调度
Basic不足
OCC(不重要)
MVCC多版本并发控制
只有写和写冲突。
故障类型
事务故障
系统故障
存储介质故障
steal/no-steal 策略
force/no-force 策略
no-force是不强制在提交前写回磁盘
no-steal是不允许在事务提交前写回磁盘
缓冲池策略
预写式日志(write-ahead log)WAL
只有当日志写到磁盘上,才能代表事务提交。
基于WAL的故障恢复
事务的分类
故障恢复时的行为
WAL协议分类
故障恢复
故障恢复
故障恢复
策略比较
WAL的问题
检查点
模糊检查点
涉及检查点的故障恢复
14-19年可通过CEAD获取
1 | https://www.ceads.net.cn/news/20211256.html |
1990-2015年的数据,可以通过MEIC获取
1 | http://meicmodel.org/?page_id=560 |
注:MEIC可以获取碳排放量统计图片
对于之后的数据获取方法:
法一:
通过
例如想知道杭州城区历年的二氧化碳排放量有多少,如图所示。
图1显示的是一个全球大气污染排放数据调用界面,我们把坐标定位到杭州城区东站附近(坐标:120.15°E,30.35°N),获取该地2020年逐月的CO2排放量数据,如图所示。
图2显示了杭州市中心地段2020年逐月的CO2排放量,可以看到2020年1月该地区CO2总排放量为3.9kg/m2,按杭州城区面积560平方公里算,可推测出2020年1月城区二氧化碳总排放量约为200万吨。
法二:
根据各省市统计年鉴计算。
如果用IPCC的算法的话,一般情况下用的都是能源平衡表,也就是用终端消费量来算各种能源的二氧化碳排放量。
挂一个可能有用的网站,碳排放交易网。
法三:
1 | https://blog.csdn.net/samLi0620/article/details/123499971 |
1997-2020年(其中2018-2020年为插值法估计)
(29.9元)
一个任务是一个处理器可以调度、执行和暂停的工作单位。它可以用来执行一个程序,一个任务或进程,一个操作系统服务工具,一个中断或异常处理程序,或一个内核或执行实用程序。
IA-32结构提供了一种机制,用于保存任务的状态,调度任务的执行,以及从一个任务切换到另一个任务。当在保护模式下运行时,所有的处理器执行都是在任务内进行的,即使是简单的系统也必须至少定义一个任务。更复杂的系统可以使用处理器的任务管理设施来支持多任务的应用。
一个过程调用包括将数据(以参数和返回值的形式)与控制从代码的一部分传递到另一部分。除此之外,在进入时为过程的局部变量分配空间,在退出的时候释放这些空间。数据传递、局部变量的分配和释放通过操纵程序栈来实现。
操作系统实现宏观上并行任务的效果,其本质是微观上在多个任务之间切换。因此,当操作系统由任务A切换到任务B时,需要暂停任务A的执行,并将处理器执行任务A时各个寄存器的值保存到内存的某个位置上,这个过程叫做保存现场;之后将处理器上一次执行任务B时各个寄存器的值由内存中的某个位置回复到处理的寄存器当中,这个过程叫做恢复现场。当操作系统在调度时由任务A切换到任务B时,对任务A保存现场,对任务B恢复现场,这个整体的过程称之为:上下文切换。
在每一个任务在执行之前,操作系统都需要为其分配一个专属的内存区域供其使用,这个内存区域通常被称为此任务的栈(stack)。Cortex-M有两个堆栈寄存器,主栈指针(MSP)与进程栈指针(PSP)。主程序操作系统和各个中断函数使用的是MSP指针,而各个被调度的任务(进程)使用的是PSP指针。本质上它是处理器的一个寄存器,PSP寄存器的值就是内存中任务的栈地址。
一个任务由两部分组成:一个任务执行空间和一个任务状态段(TSS)。任务执行空间由一个代码段、一个堆栈段和一个或多个数据段组成(见图7-1)。如果操作系统或执行程序使用处理器的特权级别保护机制,任务执行空间也会为每个特权提供一个单独的堆栈。
TSS指定了组成任务执行空间的段,并为任务状态信息提供了一个存储位置信息。在多任务系统中,TSS还提供了一种连接任务的机制。
一个任务由其TSS的段选择器来识别。当一个任务被加载到处理器中执行时,它的段选择器、基地址、限制和段描述符属性被加载到任务的寄存器。如果任务实现了分页,任务所使用的页面目录的基地址被加载到控制寄存器CR3。
以下项目定义了当前执行的任务的状态:
软件或处理器可以通过以下方式之一调度一个任务的执行。
所有这些调度任务的方法都是用一个段选择器来识别要调度的任务,这个段选择器指向任务门或任务的TSS。当用CALL或JMP指令调度任务时,指令中的选择器可以直接选择TSS或持有TSS的选择器的任务门。当调度一个任务来处理一个中断或异常时,中断或异常的IDT条目必须包含一个任务门,它持有中断或异常处理程序TSS的选择器。
当一个任务被调度执行时,在当前运行的任务和被调度的任务之间会发生一个任务切换。在任务切换期间,当前执行的任务的执行环境(称为任务的状态或上下文)被保存在其TSS中,任务的执行被暂停。被派遣任务的上下文被加载到处理器中,该任务的执行从新加载的EIP寄存器所指向的指令开始。如果任务在系统上次初始化后没有运行过,EIP将指向任务代码的第一条指令;否则,它将指向任务最后执行的指令之后的下一条指令。
如果当前执行的任务(调用任务)调用了被派发的任务(被调用任务),则段选择器被存储在被调用任务的TSS中,以提供与调用任务的链接。
对于所有IA-32处理器,任务不是递归的。一个任务不能调用或跳转到自身。中断和异常可以通过任务切换到一个处理任务来处理。在这里,处理器执行一个任务来处理中断或异常,从中断处理任务或异常处理任务返回后,自动切换回被中断的任务。这种机制也可以处理在中断任务中发生的中断。
作为任务切换的一部分,处理器也可以切换到另一个LDT,允许每个任务对基于LDT的段有不同的逻辑到物理地址的映射。在任务切换时,页面目录基础寄存器(CR3)也被重新加载,允许每个任务有它自己的一套页表。这些保护设施有助于隔离任务并防止它们相互干扰。
如果不使用保护机制,处理器不提供任务之间的保护。这一点即使在操作系统也是如此,该系统使用多个特权级别进行保护。一个运行在特权级别3的任务,使用与其他任务相同的LDT和页表。
处理器定义了五个数据结构来处理与任务有关的活动。
当在保护模式下运行时,必须为至少一个任务创建一个TSS和TSS描述符,并且TSS的段选择器必须被加载到任务寄存器中(使用LTR指令)。
恢复一个任务所需的处理器状态信息被保存在一个叫做任务状态段(TSS)的系统段中。图7-2显示了为32位CPU设计的任务的TSS的格式。TSS的字段被分为两个主要类别:动态字段和静态字段。
在任务切换期间,当一个任务被暂停时,处理器会更新动态字段。以下是动态字段。
如果包含这些结构的页面在任务切换开始前就已经存在于内存中,那么任务切换的速度会更快。
TSS,像所有其他段一样,是由段描述符定义的。图7-3显示了TSS的格式 。TSS描述符只能放在GDT中,它们不能放在LDT或IDT中。
试图使用设置了TI标志(表示当前的LDT)的段选择器访问一个TSS,会导致在CALLs和JMPs期间会产生一个一般保护异常(#GP);在IRETs期间会产生一个无效的TSS异常(#TS)。如果试图将一个TSS的段选择器加载到一个段寄存器中,也会产生一般保护异常。
类型字段中的繁忙标志(B)表示任务是否繁忙。一个繁忙的任务目前正在运行或暂停。类型字段的值为1001B表示一个不活动的任务;值为1011B表示一个繁忙的任务。
处理器使用繁忙标志来检测调用一个执行被中断的任务的尝试。为了确保只有一个繁忙标志与一个任务相关联,每个TSS应该只有一个TSS描述符指向它。
基数、极限和DPL字段以及粒度和当前标志的功能与它们在数据段描述符中的使用类似。当32位TSS描述符中的G标志为0时,极限字段必须是32位TSS描述符中的极限。TSS描述符中G标志为0时,极限字段的值必须等于或大于67H,比TSS的最小尺寸少一个字节。
试图切换到一个TSS描述符的极限值小于67H的任务,会产生一个无效的TSS异常(#TS)。如果包括一个I/O权限位图或操作系统存储了额外的数据,则需要一个更大的限制。处理器不检查任务开关上是否有大于67H的限制;但是,当访问I/O权限位图或中断重定向位图时,它将进行检查。
任何可以访问TSS描述符的程序或过程(即其CPL在数字上等于或小于的DPL)可以通过调用或跳转来调度任务。
在大多数系统中,TSS描述符的DPL被设置为小于3的值,因此只有特权软件才能进行任务切换。然而,在多任务应用程序中,一些TSS描述符的DPLs可能被设置为3,以便允许在应用程序(或用户)权限级别进行任务切换。
任务寄存器持有16位段选择器和整个段描述符(32位基本地址(在IA-32e模式下为64位 ),16位段限制和描述符属性),用于当前任务的TSS。
这个信息是从当前任务的GDT中的TSS描述符中复制过来的。图7-5显示了处理器访问TSS的路径 (使用任务寄存器中的信息)。任务寄存器有一个可见的部分(可以被软件读取和改变)和一个不可见的部分(由处理器维护,不能访问)。可见部分的段选择器指向GDT中的一个TSS描述符。处理器使用任务寄存器的不可见部分来缓存段描述符 。在寄存器中缓存这些值使得任务的执行更加有效。LTR(加载任务
寄存器)和STR(存储任务寄存器)指令加载和读取任务寄存器的可见部分。
LTR指令将段选择器(源操作数)加载到任务寄存器中,指向GDT中的TSS描述符。然后它用TSS描述符的信息加载任务寄存器的不可见部分。LTR是一个 特权指令,只有当CPL为0时才能执行。之后,当任务切换发生时,任务寄存器的内容会被隐含地改变。
STR(存储任务寄存器)指令将任务寄存器的可见部分存储在一个通用寄存器或内存中。这条指令可以被运行在任何权限级别的代码执行,以识别当前的运行的任务。然而,它通常只被操作系统软件使用。在处理器上电或复位时,段选择器和基地址被设置为默认值0;极限值
被设置为FFFH。
任务门描述符提供了对一个任务的间接的、受保护的引用(见图7-6)。它可以被放置在GDT、LDT或IDT中。任务门描述符中的TSS段选择器字段指向GDT中的一个TSS描述符。该段选择器中的RPL不被使用。任务门描述符的DPL在任务切换期间控制对TSS描述符的访问。当一个程序或过程通过任务门调用或跳转到一个任务时,指向任务门的门选择器的CPL和RPL域必须小于或等于任务门描述符的DPL。请注意,当任务门被使用时 ,目标TSS描述符的DPL不被使用。
一个任务可以通过一个任务门描述符或一个TSS描述符来访问。这两种结构都满足以下需求。
处理器在四种情况中的一种将执行转移到另一个任务。
注意事项
如果所有的检查和保存都成功进行了,处理器就会提交给任务开关。如果在步骤1到11中发生了不可恢复的错误,处理器不会完成任务切换,并确保处理器返回到执行启动任务切换的指令之前的状态。
如果一个不可恢复的错误发生在步骤12,架构状态可能会被破坏,但会试图将在先前的执行环境中处理该错误。如果一个不可恢复的错误发生在提交点之后(在步骤13),处理器完成了任务切换(不执行额外的访问和段可用性检查),并在开始执行新的任务之前产生适当的异常。
如果异常发生在提交点之后,异常处理程序必须完成任务切换本身然后才允许处理器开始执行新的任务。
当一个成功的任务切换发生时,当前执行的任务的状态总是被保存。如果该任务被恢复 ,执行将从保存的EIP值所指向的指令开始,并且寄存器被恢复到 任务暂停时的值。
当切换任务时,新任务的权限级别不会继承被暂停的任务的权限级别。新的任务以CS寄存器的CPL字段中指定的权限级别开始执行,CS寄存器是由TSS加载的。因为任务被它们独立的地址空间和TSS所隔离,并且因为特权规则控制对TSS的访问,所以任务在执行时,需要有足够的权限。
表7-1显示了处理器在切换任务时检查的异常条件。它还显示了如果检测到错误,每个检查都会产生异常,以及错误代码所引用的段。
注意
每次发生任务切换时,控制寄存器CR0中的TS(任务切换)标志被设置。在产生浮点异常时,系统软件使用TS标志来协调浮点单元与处理器其他部分的行动。
TSS的前一个任务链接字段(有时称为 “反向链接”)和EFLAGS寄存器中的NT标志被用来返回到前一个任务的执行。EFLAGS.NT=1表示当前执行的任务被嵌套在另一个任务的执行中。
当CALL指令、中断或异常导致任务切换时:处理器将当前TSS的选择器复制到新任务的TSS的前一个任务链接字段;然后设置EFLAGS.NT=1。如果软件使用IRET指令来暂停新任务,处理器检查EFLAGS.NT=1;然后使用
它使用前一个任务链接字段中的值来返回到前一个任务。见图7-8。
当JMP指令引起任务切换时,新任务不被嵌套。前一个任务链接字段不被使用,并且EFLAGS.NT=0。当不需要嵌套时,使用JMP指令来调度一个新任务。
表7-2显示了任务切换过程中的繁忙标志(在TSS段描述符中)、NT标志、前一个任务链接字段和TS标志(在控制寄存器CR0中)在任务切换期间。
NT标志可以被任何权限级别的软件所修改。一个程序有可能在设置NT标志的同时执行IRET指令。这可能会随机地调用当前任务的TSS的前一个链接字段中指定的任务。为了防止这种虚假的任务切换成功,操作系统应该把它所创建的每个TSS中的前一个任务链接字段初始化为0。
一个TSS只允许为一个任务保存一个上下文;因此,一旦一个任务被调用(派发),对任务的递归(或重入)调用该任务将导致该任务的当前状态丢失。TSS段中的繁忙标志 是为了防止重入式任务切换和随后的任务状态信息的丢失。处理器对繁忙标志的管理如下 :
处理器通过防止一个任务切换到它自己或一个嵌套的任务链中的任何任务来防止递归任务切换。由于多个调用、中断或异常,嵌套的暂停任务链可能增长到任何长度。如果一个任务在这个链中,忙碌标志会阻止它被调用。繁忙标志可以在多处理器配置中使用,因为处理器遵循一个LOCK协议(在总线上或缓存中),当它设置或清除繁忙标志时。这个锁使两个处理器不会同时调用同一个任务。
在单处理器系统中,如果有必要从链接的任务链中删除一个任务,请使用以下程序来删除
使用以下程序来删除任务。
在多进程系统中,必须在此过程中增加同步和序列化操作,以确保在改变前一个任务链接字段时,TSS和它的段描述符都被锁定并且繁忙标志被清除。
一个任务的地址空间由该任务可以访问的段组成。这些段包括代码、数据、堆栈和在TSS中引用的系统段以及任务代码所访问的任何其他段。这些段被映射到处理器的线性地址空间,而线性地址空间又被映射到处理器的物理地址空间(直接或通过分页)。
TSS中的LDT段字段可以用来给每个任务提供它自己的LDT。给予一个任务它自己的LDT允许任务地址空间与其他任务隔离,将与该任务相关的所有段描述符放在该任务的LDT中。也可以让几个任务使用同一个LDT。这是一种节省内存的方式,允许特定的任务互相通信或控制,而不丢掉整个系统的保护屏障。因为所有的任务都可以访问GDT,所以也有可能创建共享段,通过该表的段描述符来访问。
如果分页功能被启用,TSS中的CR3寄存器(PDBR)字段允许每个任务有自己的一套页表,用于将线性地址映射到物理地址。或者,几个任务可以共享同一组页表。
任务可以通过两种方式之一被映射到线性地址空间和物理地址空间。
不同任务的线性地址空间可能映射到完全不同的物理地址。如果不同页面目录的条目 指向不同的页表,而页表指向内存的不同页面,那么这些任务就不会共享物理地址。
无论采用哪种方法来映射任务的线性地址空间,所有任务的TSS必须位于物理空间的一个共享区域,这个区域是所有任务都可以访问的。这种映射是必需的,当处理器在任务切换过程中读取和更新TSSs时不会改变。线性地址空间也应该被映射到物理空间的一个共享区域;否则,GDT的目的就会落空。
图7-9显示了两个任务的线性地址空间是如何通过共享页表可在物理空间中重叠通过共享页表。
为了允许任务之间共享数据,使用以下技术为数据段创建共享的逻辑-物理地址空间映射。
9.30-9.39 背单词
9.39-9.54 看编译原理慕课
10.02-11.07 线代第一讲
11.30-11.45 线代第一讲
13.26-14.56 午觉
15.00-15.28 15.38- 16.06 线代第一讲完成
16.22-17.00 背单词
17.16-17.35 看《Linux内核完全剖析》
17.45-20.00 健身
20.09-20.44背单词
21.20-21.51 看《Linux内核完全剖析》
21.56-22.08 看实验
22.11-22.20 线代第二章
8.49-8.56 英语单词
9.05-9.45 线代第二章
10.-11.45上课
12.39 吃完饭
12.40-14.26 睡午觉
14.31 -14.53 15.00-16.58 17.10-17.17线代第二章
17.18-17.33 英语单词
17.45-20.08 锻炼
20.20-22.00 讨论
22.10-22.36 英语单词
10.00-11.47 健身
12.40-12.54 线代第二章
12.55-13.45午觉
13.45-15.30 上课,顺便完成线代第二章
15.30-16.40 打电话与学长
16.40-17.45 看实验
18.30-21.00实验课
21.00-21.52 读书笔记四
22.00-22.30 背单词
9.00-10.00 考试
10.02-10.10 单词
10.40-11.00英语听力
12.20-13.48 睡午觉
13.59-14.43 做核酸
14.43-16.05 线代第三章
16.15-16.53 完成读书笔记四
17.45-19.41 健身
19.50-20.26 背单词
20.26-20.56 打电话
21.00-21.16 交报告
21.50-22.30 听力
9.10-9.20 单词
9.37-10.37 口语训练配音
10.40-11.46 线代第三章
12.26-13.45午觉
13.45-14.20核酸
14.20-15.26 完成线代第三章
15.30-17.00 看《Linux内核完全剖析》
17.00-17.30 单词
17.45-19.45 健身
9.00-10.40 开会
10.45-11.00背单词
15.00-16.45 线代第四章
15.45-17.19 完成线代第四章
17.19-17.46 单词
19.15-21.15 数据整理
9.09-9.26 背单词
9.27-9.54 线代第五讲,注:需要重新看视频
10.00-12.17 复习完编译原理第一章
14.00-15.10 开会
15.15-16.24 复习数据库ch0
16.45-16.49 17.00-17.36 翻译英语Text5
17.45-19.30 健身
19.30-22.07 开会
22.07-22.23 单词
8.50-9.00 背单词
9.08-10.00 数据库报告
10.00-11.45 上课
14.57-15.07 查询资料
15.07-17.30 编译原理实验
17.45-19.30 健身
20.00-21.00 开会
21.30-22.32 单词
13.45-16.30 编译原理实验
16.41-17.20 单词
18.36-19.00 20.31-21.30 背单词
21.31-22.30 翻译
9.00-11.00 14.30-17.45 数据库实验
19.50-21.00 单词
21.20-23.43 实验
11.00过来做比赛
17.45-19.30健身
20.00-22.00 单词
15.00-17.00 数据库
20.47-21.31单词
8.56-9.45 看《Linux内核完全剖析》
12.56-14.35 睡觉
14.36-15.40 18.20-21.11 完成数据库实验
21.20-22.24 写论文
9.20-11.45 看《Linux内核完全剖析》
14.20-15.35 写论文
15.35-17.40 看《Linux内核完全剖析》
20.25-22.44 操作系统实验一
8.10-8.20 单词
8.50-10.00 看《Linux内核完全剖析》
12.10-12.20 操作系统实验一
14.30-15.38 完成操作系统实验一
15.53-17.00 数据库实验四
20.05-23.47 实验
白天看实验,看了一天
20.30-23.59 写比赛论文
9.00-9.05 单词
9.05-9.50 写实验报告
9.51-11.00 实验
14.30-16.39 完成报告与数据库第二章复习
16.40-17.20 编译原理第二讲
20.00-20.56写论文
13.00-13.30 单词
13.30-13.38 14.24-16.36 数据库第三章
20.30-21.52 写论文
14.46-15.03 复习编译原理第三章
15.03-15.48 改论文
9.00-9.45 单词
9..45-9.55 改论文
14.30-16.30 18.30-22.20 线代第五章完成
9.00-9.19 背单词
9.21-11.20 14.56—16.40 线代第六章
16.58-17.20数据库复习第四章
19.44-21.39 完成数据库第四章与部分第五章
22.10-22.40 英语听力
9.25-9.55 单词
15.10-17.16 做操作系统实验二
20.00-21.58 完成操作系统实验二
22.00-23.00 复习国际结算
8.53-9.10 单词
9.14-11.00 完成国际结算
14.47-17.20 数据库第五章
21.00-23.00 数据库第五章完成