自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(82)
  • 收藏
  • 关注

原创 docker学习

docker镜像本质上是一个压缩包,里面包含所有运行这个程序所需的所有文件,如bin,lib,usr,etc等。docker利用Linux内核技术建造一个用户进程,该用户进程认为自己是完整的用户态(或者说它认为自己是pid1,是第一个用户进程)。my-web是被修改容器的容器名,new-nginx是新镜像的名字。docker pull nginx:pull的作用是拉取镜像,这里拉取的是官方的nginx镜像以作示例。-p 80:80 的作用是端口映射,把容器里的80端口(右边)连接到电脑的80端口(左边)

2026-02-25 09:12:54 219

原创 lectrue19 日志方案

因为LSM的内存部分在断电时会丢失,用户写入数据时,先把这个操作写入WAL文件中(为了防止断电),再把数据插入到内存中的MemTable,当MemTable满了之后,刷到磁盘中变成SSTable(这是LSM的持久化部分),此时,对应的WAL文件被删除。日志结构化系统(LSM):这就是我们之前在lectrue4中学到的日志结构存储,此结构下,内存中我们有一张跳表mtable,mtable中存储的是日志记录,日志记录中的日志条目记录操作而非对应元组的完整状态。当事务提交时,把影子副本原子性地切换为新的主副本。

2026-02-23 10:12:09 863

原创 lecture18 多版本并发控制

否则,如果更新被索引的列值并把索引项改为指向新版本时,旧key的索引条目就被覆盖丢失,老事务找不到旧版本了。MVCC 重复键问题(MVCC Duplicate Key Problem)描述的正是当多个事务需要同一逻辑元组的多个版本时,索引必须支持重复键的需求。因此,在一次索引查找中,工作线程可能会得到多个条目(对应不同版本),随后必须沿着指针追溯,找到对该事务实际可见的物理版本。版本存储:这里讲的是 DBMS 如何存放同一逻辑对象的不同物理版本,以及事务如何在运行时找到对其可见的最新版本。

2026-02-22 21:02:57 654

原创 lectrue17 时间戳排序并发控制

注:前面的三种情况本身是充分的并发安全条件,但它们要求的交集检测是按照谓词/语义范围来做的,而不是按已读到的具体行ID来做。而简单的OCC通常只比较具体ID(例如ReadSet就是事务T1已读的行集合,但当另一个事务T2插入一个新的满足谓词条件的元组时,这个元组并不会自动插入到事务T1的ReadSet中,除非T1重新执行扫描或采用其他策略避免幻影问题)。为了只允许可串行化的调度,DBMS 检查正在提交的事务 Ti 与其他事务之间的读-写(RW)和写-写(WW)冲突,并确保所有冲突单向发生。

2026-02-21 21:50:30 957 1

原创 lectrue16 二阶段锁

例如:在一个B+树中,进行扫描时你只需要持有单个叶子节点地Latches,因为这足以确保物理结构的正确性,但如果一个事务试图扫描叶子节点,而另一个事务试图同时修改两个任意值,那么扫描事务需要锁定整个表(不仅仅是当前的叶子节点),以避免只看到两次写入中的一次(保证逻辑一致性)。当事务在层次结构中获取某个对象的锁时,它隐式地获取了该对象所有子对象的锁(例如锁了表,就等于锁了表里的所有行)。意向锁:重要的一点是,如果一个事务正在使用元组级锁,他需要告知系统,其他事务不能获取页级锁,因为这回产生冲突。

2026-02-20 16:28:17 797

原创 lectrue15 并发控制理论

并发执行的需求:一个(潜在的)更好的方法是允许独立事务的并发执行,同时保持正确性和公平性(即所有事务被平等对待,不会因为永远无法执行而陷入“饥饿”状态)。数据库一致性:数据库准确地反映了它所建模地真实世界实体,并遵循完整性约束,例如人的年龄不能为负数,此外,未来的事务应该能看到数据库中过去已提交事务所产生的影响。DBMS执行操作的顺序被称为执行调度,我们的目标是交错执行事务以最大化并发量,同时确保输出是正确的。事务一致性:如果数据库在事务开始前是一致的,那么在事务完成后也必须是一致的。

2026-02-20 15:36:21 546

原创 lectrue14 查询规划和优化

在这个例子中,优化器通过将嵌套查询提取为独立的查询,并随后利用该结果实现原始查询的逻辑,从而分解了一个带有嵌套聚合的查询,将之前的嵌套查询变为了一个带有常量过滤条件的单层查询。但是,执行查询计划中的每个算子都有不同的方式(例如不同的连接算法),且这些计划之间的性能存在差异。例如,如果我们假设合取谓词(即AND连接的条件)中涉及的多个谓词是相互独立的,我们可以将该合取条件的总选择率计算为各个独立谓词选择率的乘积。计划枚举:在执行完基于规则的重写之后,DBMS会为该查询枚举出不同的执行计划并估算它们的代价。

2026-02-20 14:45:39 789

原创 project3

通过观察CreateExecutor函数,我们发现在一次查询中,我们始终使用同一exec_ctx,而每个执行器都独占一个PlanNode。关于索引,一张表可能有多个索引,可能对于学生表来说,既把它的id作为索引,又把它的成绩作为索引。3.索引维护的原子性:在修改一行时,如果中间某个索引插入失败(比如唯一键冲突),而你已经把前面的几行给改了且“流”给了上层,这时候很难进行局部的回滚。注:在窗口函数的实现过程中,哈希表的键则为partition_by,如果有多个partition_by,则应该建多张哈希表。

2026-02-19 21:52:36 679

原创 lectrue13 查询处理

每工作单元一个进程:最基础的方法是每工作单元一个进程。算子间并行:在算子间并行中,DBMS重叠执行算子,以便将数据从一个阶段以流水线方式传送到下一阶段,而无需物化,这有时被称为流水线并行,参考下图中,JOIN算子每产生一个结果元组,就立刻将其推送到上方的PROJECTION算子中。下图中:对于左边的语句,传统的执行方式是开启一个算子实例,按顺序扫描表A中的每一页,逐个检查value>99的条件。背景:此前关于查询执行的讨论都假设查询是由单个工作线程执行的,然而在实践中,查询通常是由多个工作线程并行执行的。

2026-02-04 15:30:37 600

原创 lectrue12 查询处理

每个页面的区域图存储在单独的页面中,通常每个区域图页面包含多个条目。有些算子会阻塞,直到子节点发送完它们所有的元组,这类算子的例子包括连接,子查询和排序,这类算子被称为流水线中断器。更高级的DBMS支持多索引扫描,当为一个查询使用多个索引时,DBMS会利用每个匹配的索引计算出记录ID的集合,根据查询的谓词合并这些集合,检索记录,并应用任何剩余的谓词。迭代模型支持流水线化,即DBMS在必须获取下一个元组之前,可以让一个元组尽可能多地通过多个算子,在查询计划中针对给定元组执行的一系列任务被称为一个流水线。

2026-02-04 14:27:43 1009

原创 lectrue11 连接算法

排序后归并连接的优越性:举个简单的例子,对比一次之后,如果发现A匹配的外键是100,而B中的当前指针指向主键是120的话,并且B中主键从小到大排序的话,就可以一次比较就认定匹配失败,而不需要遍历整张表。2.探测:扫描内部关系,对每个元组的连接属性使用相同的哈希函数 h1,跳转到哈希表中的对应位置并寻找匹配的元组。DBMS总是希望将较小的表作为外部表,较小可以是指元组的数量,也可以是页面的数量,DBMS还希望尽可能多地将外部表缓冲在内存中,此外,它还可以尝试利用索引来寻找内部表中地匹配项。

2026-02-02 09:20:58 764

原创 lectrue10 排序和聚合算法

C++中的模板特化就是一个例子,另一种针对字符串比较的优化是后缀截断,长VARCHAR键的二进制前缀可以先进行相等检查,只有当前缀相等,才会回退到较慢的标准字符串比较。哈希:在计算聚合时,哈希的计算开销可能比排序更低。重哈希:对于磁盘上的每个分区,将其页面读入内存,并基于第二个哈希函数h2(h1≠h2)构建内存哈希表,然后遍历该哈希表的每个桶,将匹配的元组汇集在一起以计算聚合。对于面向磁盘的数据库系统,我们将利用缓冲池来实现那些在处理过程中需要溢出到磁盘的算法,我们的核心目标是尽可能减少算法的I/O次数。

2026-02-01 10:51:25 852

原创 lectrue9 索引并发控制

在Header和Directory的Init函数中,在初始化时应该将页号数组初始化为INVALID_PAGE_ID(Header必须,Directory建议,因为目录页和桶页可以通过Size来判断,而Header只能通过判断值是否为INVALID_PAGE_ID来判断对应的目录页是否已经存在)。假如不安全,由于在检查插入L过程中始终持有父亲的锁,父亲在这个过程中始终保持安全(或父亲的某个祖先始终保持安全),此时向L中插入后,最远波及到安全的父亲或安全的父亲的某个祖先,由于节点安全,所以影响不会再往上波及。

2026-01-30 11:50:35 942

原创 lectrue8 表索引

以下图为例,假设键为(列1,列2)这个整体,对于哈希函数,我们必须提供('A','C')才能计算出对应的哈希值,进而得到对应的值。需要注意,在物理内存中,存储键值对以数组的方式存储,但在逻辑上仍然是一棵B+树,DBMS应该保存B+树根节点的地址,否则整棵树成为毫无意义的垃圾。或允许叶子节点溢出到包含重复键的溢出节点中。前缀压缩:在同一个节点的键通常会有部分重叠的前缀(因为 B+ 树是有序的,相似的键会排在一起),与其在每个键中重复存储前缀,不如在节点开头存储一次前缀,然后在每个槽位中只包含该键特有的部分。

2026-01-23 21:42:48 491

原创 lectrue7 哈希表

在实践中,布谷鸟哈希通常是在单个哈希表上使用多个哈希函数将键映射到不同槽位,此外,由于哈希计算本身有开销,其查找和删除的成本实际上可能略高于理想的O(1)。布谷鸟哈希:这种方法不只使用一个哈希表,而是维护多个具有不同哈希函数(通常算法相同但种子不同,如不同种子的 XXHash)的哈希表。当任何桶发生溢出时,拆分指针当前位置的桶。添加一个新的槽条目和一种新的哈希函数,并应用此函数对拆分桶中的键进行重哈希。1.哈希函数:它告诉我们如何将一个巨大的键空间映射到一个较小的目标域中,用于计算桶或槽数组的索引。

2026-01-23 12:09:00 297

原创 lectrue6 缓冲池

操作系统页缓存:大多数磁盘操作都是通过os的API完成的,除非被显式告知执行其他操作,否则操作系统会维护其自有的文件系统缓存,也被称为页缓存。普通I/O时,内核将页缓存上的文件内容复制到用户空间的某一块内存上,双重缓冲的代价是难以接受的。这样做是为了避免在内存中存储冗余的数据页副本,并防止需要同时处理两套不同的缓存淘汰策略(即 DBMS 自身的策略与操作系统的策略)。锁保护的是用户的业务数据,如果一个事务在更新元组的中途失败了,系统必须能够撤销对该元组的修改,回到初始状态,因此锁必须与事务的原子性挂钩。

2026-01-23 10:28:33 530

原创 lectrue5 存储模型和压缩

由于访问数据需要先解压,这限制了压缩方案的作用域,如果目标是将整张表压缩成一个巨大的数据块,使用朴素压缩方案将是行不通的,因为每次访问都需要对整张表进行压缩/解压,而朴素算法需要从文件的开头解压,直到还原出你需要的位置的数据。数据库压缩:由于磁盘I/O几乎始终是性能的主要瓶颈,压缩技术在基于磁盘的DBMS中得到了广泛应用,它在具有只读分析型负载的系统中尤为流行,如果元组事先经过压缩,DBMS就能一次性获取更多有用的元组,代价是压缩和解压会带来更大的计算开销。因此,该列中的每一个值都必须具有相同的长度。

2026-01-22 22:02:56 384

原创 lectrue4 数据库存储

这在时间和空间上都是不可接收的。在索引组织存储的方案中,DBMS直接将表的元组作为索引数据结构中的值进行存储,在这种模式下,DBMS会使用类似于插槽页的页面布局,并且元组在页面内通常是按照键进行排序存储的。注:SSTable之间是有时间顺序的,假如最新的SSTable和一个旧的SStable之间都有关于元组A的信息,那么显然应该使用最新SSTable的记录。第二次提交:假如第一次提交之后,第二次提交之前,有甲在4登录,乙在5登录,丁在7登录,它们三人的登录时间又被压缩为一个SSTable并提交到磁盘中。

2026-01-22 21:14:51 538

原创 lectrue3 数据库存储

面向磁盘的DBMS:数据库全部存储在磁盘上,数据库文件中的数据被组织成数据页,其中第一页是目录页。这意味着,如果我们的数据库页大于硬件页(例如16KB),DBMS就必须采取额外措施来确保数据安全写入,因为如果在程序将数据库页写入磁盘的过程中(比如只写了前 4 KB)系统发生了崩溃,就会导致页面损坏(部分写入)。稻草人方案:一种简单但有缺陷的方案是,记录页中存储的元组数量,每次添加新元组时直接追加到末尾,然而,当元组被删除或元组包含变长属性(如字符串)时,这种方法就会产生问题(碎片化问题)。

2026-01-22 16:04:22 551

原创 lectrue2 高级SQL

我们向WHERE输入一个完整的元组,然后将元组中的数据带入WHERE后的公式中,TRUE则留库,FALSE则丢弃。在生成表后,数据库会扫描表并根据e.cid进行物理或逻辑上的分类,数据库为每一个唯一的cid创建一个桶,一旦分组完成,数据库在每个桶的内部独立运行聚合函数。FROM:FROM是SQL执行逻辑的第一步,其作用是定义查询的初始数据集,这个空间可以是一张简单的表,也可以是多个表的组合。COUNT(1),为结果集的每一行分配一个常量,然后统计这个常量出现了多少次,它和COUNT(*)一样快。

2026-01-18 20:19:07 679

原创 lectrue1 关系模型和代数

数据库(Datebase):一个组织好的数据集合。用于模拟现实世界中的某个方面。数据库管理系统(DBMS):管理数据库的软件,比如MYSQL,Oracle,以及我们的BusTub。平面文件方案:在该方案中,数据库被存储为由DBMS管理的逗号分隔值(CSV)文件。每个实体都存储在独立的文件中。每当应用程序想要读取或更新记录时,都必须重新解析这些文件。

2026-01-18 16:36:15 497

原创 中断处理——lab net中为什么e1000_recv必须批量处理

物理设备和设备控制器和中断控制器:网卡,声卡,显卡,键盘鼠标这些所有都是物理设备,而管理这些设备的叫设备控制器。但是设备控制器需要引起CPU关注时,它作为中断源,必须向中断控制器发送信号,中断控制器负责仲裁优先级,最后向CPU发起真正的中断。当CPU处理完这个中断后,又能看到下一次中断的信号,然后继续处理第二次中断的数据包。但是,由于只能记录0和1,所以0和1只能抽象为无数据包和有数据包的简单逻辑,而我们的recv函数也只知道有数据包,而不知道有多少数据包,因此采取批量处理是必然的。

2026-01-06 10:19:36 430

原创 lectrue21 networking

注:基于这位大佬的中文翻译笔记学习,有大段对翻译笔记的直接引用,以及一部分询问AI和结合自己理解的一些内容。写这份笔记只是为了方便自己复习和理解。计算机网络概述:网络是操作系统的重要组成部分。本节课将探讨操作系统中网络软件的架构。本节课程将为最后一个 Lab(构建 E1000 网卡驱动)提供理论基础。同时将深入讨论Livelock论文,分析在设计高吞吐量网络协议栈时可能遇到的性能陷阱(如中断风暴导致系统瘫痪)。

2026-01-06 09:42:28 662

原创 大端序和小端序

例如有一本书,大端序展示的就是书本正常内容,小端序就是将第一页的内容完全倒序,第二页的内容完全倒序......但是第一页的内容永远在第一页上,第二页的内容永远在第二页上。如果接收端同样也是小端序,那么先接受到低位字节,然后把先接受到的数据填入低地址,就能得到正确的数据。如果接收端同样也是大端序,那么先接受到高位字节,然后把先接受到的数据填入低地址,就能得到正确的数据。注:明确一点,当我们谈论一个指针指向的数据时,指针指向的是这个数据的最低地址,如果一个数据的地址范围是p到p+8,指针就是p。

2026-01-05 09:44:44 314

原创 lectrue23 多核并行性能

注:基于这位大佬的中文翻译笔记学习,有大段对翻译笔记的直接引用,以及一部分询问AI和结合自己理解的一些内容。写这份笔记只是为了方便自己复习和理解。使用锁带来的问题目标:多核性能扩展。在现代计算机(拥有 4、8、64 甚至更多 CPU 核)上,操作系统内核应该是一个高效的并行程序。理论上,如果内核能在 N 个核上并行运行,性能应该是单核的 N 倍。对于互不相关的进程(例如读写不同的文件、使用不同的管道),它们天然就是独立的,可以毫无障碍地并行运行。

2026-01-04 20:18:10 786

原创 lectrue22 Meltdown

注:基于这位大佬的中文翻译笔记学习,有大段对翻译笔记的直接引用,以及一部分询问AI和结合自己理解的一些内容。写这份笔记只是为了方便自己复习和理解。Meltdown(熔断)漏洞Meltdown引入:操作系统的承诺:内核通过页表(Page Table)和硬件的特权级(User/Supervisor Mode)来保证安全。基本假设是:用户程序绝对无法读取内核内存,因为硬件会阻止这种非法访问。

2026-01-04 18:47:03 524

原创 TLB 和 Cache

Cache控制器直接截取VA的Index位,作为地址输入到L1 Cache中,根据Index,Cache选中对应的组,并将组内所有缓存行的数据和Tag(简单处理为PPN)读出。地址切分:目前为止在xv6中学习的所有对地址的索引方式都是通过这种地址切分的方式进行的,地址切分实际上就是一个数学的游戏,在设计时,我们需要根据硬件的物理规格倒推出来需要切分多少位地址。键:当CPU发出一个虚拟地址请求时,硬件会将虚拟地址的高位和TLB中的键进行并行对比,TLB的键包含以下信息,所有信息匹配,则键匹配成功。

2026-01-04 16:41:00 541

原创 lectrue20 比较用C和HLL实现OS的优劣

注:基于这位大佬的中文翻译笔记学习,有大段对翻译笔记的直接引用,以及一部分询问AI和结合自己理解的一些内容。写这份笔记只是为了方便自己复习和理解。C语言实现OS的优劣引入:学生和开发者经常质疑,为什么非要用C,如果换种语言,是否能避免一堆烦人的bug。虽然社区对此争论不休,但缺乏实际的数据支持。本节课讨论的论文旨在通过构建一个真实的内核,提供量化的数据和深入的分析,而非一个简单的是或否。

2026-01-03 20:13:21 1067

原创 lecture19 虚拟机

注:基于这位大佬的中文翻译笔记学习,有大段对翻译笔记的直接引用,以及一部分询问AI和结合自己理解的一些内容。写这份笔记只是为了方便自己复习和理解。虚拟机:虚拟机本质上是对计算机硬件的模拟,其模拟的精确程度足以运行一个未经修改的操作系统。下面是一些相关术语:位于硬件最底层,取代了传统操作系统内核的位置。Host 空间:运行 VMM 的区域。主要职责:模拟多个计算机环境,管理硬件资源,使得上层软件(Guest OS)认为自己独占硬件。Guest 空间(客户机空间):运行在 VMM 之上。

2026-01-03 18:22:53 633

原创 lectrue18 微内核

注:基于这位大佬的中文翻译笔记学习,有大段对翻译笔记的直接引用,以及一部分询问AI和结合自己理解的一些内容。写这份笔记只是为了方便自己复习和理解。以下内容基本全由AI总结生成,因为我没有细读过论文,大概就当科普一下吧。。。宏内核:宏内核是一种传统的操作系统架构,将所有的核心功能(如文件系统、虚拟内存管理、调度器、设备驱动等)集成在一个巨大的、单一的可执行程序中。整个内核代码都运行在硬件的最高权限模式(Supervisor Mode / Kernel Mode)下,拥有对硬件的绝对控制权。

2026-01-02 21:08:42 517

原创 lec17 用户级虚拟内存

类似于内核处理Page Fault,用户程序需要一种机制,当发生缺页或权限违规时,CPU能暂停当前执行,跳转到用户自定义的Handler处理,处理完后恢复执行。3.用户可以自定义置换策略,普通的Lazy Allocation由内核决定何时回收页面(通常是内存不够时),在这个例子中,用户程序自己决定:“我只要这一个页,其他的都丢掉”。3.Handler会扫描该页的所有对象,发现对象内部如果有指向From空间的指针,就将这些被指向的对象Forward(拷贝)到To的末尾(新开辟的Unscanned页)。

2026-01-02 20:10:35 882

原创 总线模型。

设备之间的通信可以并行进行,一个Master端口实际上包含5组独立的总线,分别是写地址,写数据,写响应,读地址,读数据通道,这样,端口可以同时发送和接受数据。现代总线可以抽象为一束集成了写地址,写数据,写响应,读地址,读数据五种功能的逻辑连接线(物理上它可能涉及几百根铜线,但对我们来说,这就是一个交互接口)。让CPU,内存和显卡等在一组,它们拥有极高带宽,极低盐池。1.早期单总线模型:所有设备——CPU,内存,所有外设都挂在同一组电线上,这组电线包括三类信号,地址线,数据线和控制线。

2026-01-02 09:34:43 142

原创 lec16 ext3中的日志机制

此时,磁盘的文件系统中,目录A中可能有文件x,目录B中可能有文件y,前者记录inode17指向文件x,后者记录inode17指向文件y。几乎所有需要故障恢复的存储系统(数据库,文件系统,定制系统)都使用它,在分布式系统中也是从崩溃中恢复状态的核心机制,它是对“崩溃前发生的所有事件”的数据结构化记录,理解它就能掌握系统恢复的关键。事务切换时,会有短暂阻塞。T1的执行依赖于T2的中间状态,T2本来应该全做或者全不做,但在上述场景中,由于T1的固化,T2的一部分效果被永久保留了,而另一部分却因崩溃消失了。

2025-12-29 21:20:48 823

原创 机械硬盘如何工作

扇区是硬盘读写的最小物理单位,读写一个磁盘块,本质上就是读写几个连续的扇区。表面涂有一层极薄的磁性材料,数据就是通过改变这些微小颗粒的磁极方向来记录0和1。磁头已经到位,但是磁头只能原地不动,等盘片旋转,把那个扇区到磁头底下才能读取数据,这是另一个瓶颈,大约平均耗时4ms。耗时大约3到10ms,这是最慢的一步。磁头:磁头负责读写盘片上的数据。由于盘片是双面的,所以磁头的数量通常为盘片数量*2。磁道:磁道是无数个独立的同心圆,从最外圈开始向圆心编号,最外圈是0磁道。机械硬盘有三个核心组件:盘片,磁头和磁道。

2025-12-29 20:57:23 172

原创 lectrue14 15,xv6中的文件系统

xv6 教材 文件系统:文件系统的目的是组织和存储数据。文件系统通常支持在用户和应用程序之间共享数据,以及提供持久性,以便数据在重启后仍然可用。 xv6文件系统提供了类Unix的文件、目录和路径名,并将其数据存储在virtio磁盘上以实现持久化,文件系统需要解决下面几个问题: 1.磁盘数据结构:文件系统需要磁盘上的数据结构来表示命名目录和文件的树状结构,记录保存每个文件内容的块的身份,并记录磁盘的哪些区域是空闲的。 2.崩溃恢复:文件系统必须支持崩溃恢

2025-12-29 10:39:37 1087

原创 lectrue13,xv6中sleep、wakeup、wait、exit、kill的实现

然后它扫描进程表,如果发现一个处于ZOMBIE状态的子进程,它会释放该子进程的资源及其proc结构,将子进程的退出状态复制到提供给wait的地址,并返回子进程的PID。xv6记录子进程死亡直到wait观察到它的方式是:exit将调用者置于ZOMBIE状态,它会一直保持该状态,直到父进程的wait注意到它,将其状态更改为UNUSED,复制子进程的退出状态,并将子进程的PID返回给父进程。Linux内核的sleep使用一个显式的进程队列,称为等待队列,而不是通过等待通道,该队列有自己的内部锁。

2025-12-19 19:12:44 561

原创 ASP.NET 期末突击

PPT第一章: C/S结构:使用局域网。客户端响应速度快,但可维护性差。 B/S结构:适用于广域网环境。应用程序及数据库系统都安装在服务器上,客户端只需安装一个浏览器软件。处理功能都运行在服务器端。维护方便,但服务器负担重。 两层架构:用户——表示逻辑层——数据库层 三层架构:用户——表示逻辑层——商务逻辑层——数据库层 N层架构:用户——表示逻辑层——商务逻辑层——服务层——数据库层 .NET FRAMEWORK主要包括C

2025-12-15 08:28:49 545

原创 lectrue11,上下文切换

如何确保一个CPU的调度器进程独有:普通进程住在全局数组proc中,但调度器进程根本不在这张表中,调度器的上下文被保存在struct cpu的context字段中,调度器的栈(Stack)是内核启动时专门为每个 CPU 分配的独立内存页。allocproc函数会将上下文中的ra设置为forkret的地址,意味着当调度器第一次切换到这个新进程时,swtch会返回到forkret函数的开头,sp被设置为新分配的内核栈顶,其他寄存器初始化为0,因为没有需要继承的旧的寄存器状态。xv6的策略结合了上述两者。

2025-12-07 18:11:25 676

原创 lectrue10,并发与锁

注:基于这位大佬的中文翻译笔记学习,有大段对翻译笔记的直接引用,以及一部分询问AI和结合自己理解的一些内容。写这份笔记只是为了方便自己复习和理解。 https://github.com/huihongxiao/MIT6.S081 并发(concurrency):指的是内核中多个任务交替执行的情景,主要有: 多处理器硬件(多个CPU同时运行并分享物理内存) 线程切换:即使在单核CPU上,内核也会在不同线程间切换

2025-12-06 18:14:36 526

原创 lectrue9,中断

网卡,声卡,显卡,键盘鼠标这些所有都是物理设备,而管理这些设备的叫设备控制器。DMA(直接内存访问):UART驱动程序通过读取UART控制寄存器一次获取一个字节的数据,这种模式叫程序控制I/O,这种方式虽然简单,但对于高数据速率来说太慢了,需要高速传输大量数据的设备通常直接使用DMA,DMA设备硬件直接将传入数据写入RAM,并从RAM读取传出数据。设备之间的通信可以并行进行,一个Master端口实际上包含5组独立的总线,分别是写地址,写数据,写响应,读地址,读数据通道,这样,端口可以同时发送和接受数据。

2025-12-01 20:42:04 580

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除