操作系统 3.6-内存换出

news2025/5/17 10:52:15

换出算法总览

页面置换算法

  1. FIFO(先进先出)

    • 最简单的页面置换算法,淘汰最早进入内存的页面。

    • 优点:实现简单。

    • 缺点:可能会导致Belady异常,即增加内存反而降低性能。如果刚换入的页面马上又要换出,FIFO的性能会很差。

  2. MIN(最小使用时间)

    • 理论上的最优算法,淘汰预计在未来最长时间不会被使用的页面。

    • 优点:理论上最优,可以保证最低的缺页率。

    • 缺点:实现复杂,因为需要预测页面未来的使用情况。

  3. LRU(最近最少使用)

    • 淘汰最长时间未被访问的页面。

    • 优点:性能接近最优,实现相对简单。

    • 缺点:需要跟踪每个页面的使用历史,增加了系统开销。

FIFO

在操作系统中,FIFO(先进先出)页面置换算法是一种常见的页面置换策略

FIFO工作流程

FIFO(先进先出)页面置换算法是一种简单的页面置换策略,它基于这样一个原则:最早进入内存的页面将是最早被替换出去的页面。这种算法易于实现,但可能不是最高效的页面置换策略。下面是FIFO页面置换算法的工作流程:

  1. 页面命中

    • 如果页面已经在内存中,那么这是一个页面命中(page hit),不需要进行页面置换。

  2. 页面缺失

    • 如果页面不在内存中,那么这是一个页面缺失(page fault),需要进行页面置换。

    • 检查是否还有空的页框可用。如果有,将新页面加载到空的页框中。

    • 如果没有空的页框,根据FIFO算法,选择队列中最早进入内存的页面进行替换。

  3. 页面置换

    • 将选中的页面从内存中移除,并将新页面加载到该页框中。

    • 更新队列,将新页面添加到队列的末尾,并移除被替换的页面。

  4. 更新引用序列

    • 继续处理程序的页面引用序列,重复步骤2-5,直到所有页面引用都被处理。

  5. 评估性能

    • 计算缺页次数(page faults),这是评估页面置换算法性能的主要指标之一。

案例分析

根据您提供的幻灯片内容,我们可以看到一个具体的例子,其中分配了3个页框,页面引用序列为 ABCABDADBCBCB

在这个例子中,FIFO算法导致了7次缺页。在这个例子中,如果我们按照FIFO算法来操作,我们会看到以下置换过程:

  1. 开始时,内存为空,引用序列为 A B C A B D A D B C B

  2. 当引用 A 时,将其放入第一个页框,没有发生缺页。

  3. 引用 B 时,将其放入第二个页框,没有发生缺页。

  4. 引用 C 时,将其放入第三个页框,没有发生缺页。

  5. 再次引用 A 时,因为 A 已经在内存中,没有发生缺页。

  6. 引用 B 时,因为 B 已经在内存中,没有发生缺页。

  7. 引用 D 时,需要替换掉最早进入的 A,发生缺页。

  8. 引用 A 时,需要替换掉最早进入的 B,发生缺页。

  9. 引用 D 时,因为 D 已经在内存中,没有发生缺页。

  10. 引用 B 时,需要替换掉最早进入的 C,发生缺页。

  11. 引用 C 时,需要替换掉最早进入的 A,发生缺页。

  12. 引用 B 时,因为 B 已经在内存中,没有发生缺页。

在这个过程中,总共发生了7次缺页。

MIN

MIN页面置换算法,也被称为OPT(Optimal,最优)算法,是一种理论上最优的页面置换算法。它选择将来最长时间内不会被使用的页面进行置换。由于MIN算法需要知道未来的页面引用信息,这在实际中是不可能的,因此它通常用于理论分析和比较其他算法的性能。

MIN算法工作流程

  1. 初始化

    • 假设系统有固定数量的页框(page frames),用于存储内存中的页面。

  2. 页面引用

    • 当程序引用一个页面时,系统检查该页面是否已经在内存中(即是否在页框中)。

  3. 页面命中

    • 如果页面已经在内存中,那么这是一个页面命中(page hit),不需要进行页面置换。

  4. 页面缺失

    • 如果页面不在内存中,那么这是一个页面缺失(page fault),需要进行页面置换。

    • 检查所有在内存中的页面,确定哪个页面在未来最长时间内不会被引用。

  5. 页面置换

    • 将选中的页面从内存中移除,并将新页面加载到该页框中。

  6. 更新引用序列

    • 继续处理程序的页面引用序列,重复步骤2-5,直到所有页面引用都被处理。

  7. 评估性能

    • 计算缺页次数(page faults),这是评估页面置换算法性能的主要指标之一。

图中案例分析

在图中的案例中,我们有3个页框,页面引用序列为 ABCABDADBCBCB。根据MIN算法,我们可以看到以下置换过程:

  1. 开始时,内存为空,引用序列为 A B C A B D A D B C B

  2. 引用 A 时,将其放入第一个页框,没有发生缺页。

  3. 引用 B 时,将其放入第二个页框,没有发生缺页。

  4. 引用 C 时,将其放入第三个页框,没有发生缺页。

  5. 再次引用 A 时,因为 A 已经在内存中,没有发生缺页。

  6. 引用 B 时,因为 B 已经在内存中,没有发生缺页。

  7. 引用 D 时,需要替换掉将来最长时间内不会被使用的页面。在这个例子中,C 在未来的引用序列中出现的最晚,因此被替换,发生缺页。

  8. 引用 A 时,因为 A 已经在内存中,没有发生缺页。

  9. 引用 D 时,因为 D 已经在内存中,没有发生缺页。

  10. 引用 B 时,因为 B 已经在内存中,没有发生缺页。

  11. 引用 C 时,需要替换掉将来最长时间内不会被使用的页面。在这个例子中,A 在未来的引用序列中出现的最晚,因此被替换,发生缺页。

  12. 引用 B 时,因为 B 已经在内存中,没有发生缺页。

在这个过程中,总共发生了5次缺页。

LRU

LRU(最近最少使用)页面置换算法是一种非常流行且有效的页面置换策略。它基于这样一个假设:如果一个页面最近被访问过,那么它在未来很可能也会被访问;相反,如果一个页面很长时间没有被访问,那么它在未来被访问的可能性就较小。因此,LRU算法会选择最长时间未被访问的页面进行置换。就是用历史推测未来

LRU算法工作流程

  1. 初始化

    • 假设系统有固定数量的页框(page frames),用于存储内存中的页面。

    • 初始化一个数据结构(如链表或栈),用于跟踪每个页面最后一次被访问的时间。

  2. 页面引用

    • 当程序引用一个页面时,系统检查该页面是否已经在内存中(即是否在页框中)。

  3. 页面命中

    • 如果页面已经在内存中,那么这是一个页面命中(page hit)。更新该页面的最后访问时间。

  4. 页面缺失

    • 如果页面不在内存中,那么这是一个页面缺失(page fault),需要进行页面置换。

    • 检查所有在内存中的页面,确定哪个页面最长时间未被访问。

  5. 页面置换

    • 将选中的页面从内存中移除,并将新页面加载到该页框中。

    • 更新新页面的最后访问时间。

  6. 更新引用序列

    • 继续处理程序的页面引用序列,重复步骤2-5,直到所有页面引用都被处理。

  7. 评估性能

    • 计算缺页次数(page faults),这是评估页面置换算法性能的主要指标之一。

图中案例分析

在图中的案例中,我们有3个页框,页面引用序列为 ABCABDADBCBCB。根据LRU算法,我们可以看到以下置换过程:

  1. 开始时,内存为空,引用序列为 A B C A B D A D B C B

  2. 引用 A 时,将其放入第一个页框,没有发生缺页。

  3. 引用 B 时,将其放入第二个页框,没有发生缺页。

  4. 引用 C 时,将其放入第三个页框,没有发生缺页。

  5. 再次引用 A 时,因为 A 已经在内存中,更新其最后访问时间,没有发生缺页。

  6. 引用 B 时,因为 B 已经在内存中,更新其最后访问时间,没有发生缺页。

  7. 引用 D 时,需要替换掉最长时间未被访问的页面。在这个例子中,C 是最长时间未被访问的页面,因此被替换,发生缺页。

  8. 引用 A 时,因为 A 已经在内存中,更新其最后访问时间,没有发生缺页。

  9. 引用 D 时,因为 D 已经在内存中,更新其最后访问时间,没有发生缺页。

  10. 引用 B 时,因为 B 已经在内存中,更新其最后访问时间,没有发生缺页。

  11. 引用 C 时,需要替换掉最长时间未被访问的页面。在这个例子中,A 是最长时间未被访问的页面,因此被替换,发生缺页。

  12. 引用 B 时,因为 B 已经在内存中,更新其最后访问时间,没有发生缺页。

在这个过程中,总共发生了5次缺页。

时间戳实现

图中展示了如何使用时间戳来准确实现LRU(最近最少使用)页面置换算法。这种方法通过为每个页面维护一个时间戳来记录页面最后一次被访问的时间。当需要进行页面置换时,选择具有最小时间戳的页面进行淘汰,即该页面是最近最少使用的。

实现步骤

  1. 初始化

    • 为每个页面分配一个时间戳变量,初始值设为0。

    • 设置一个全局时钟,用于生成时间戳。

  2. 页面引用

    • 当程序引用一个页面时,系统检查该页面是否已经在内存中。

  3. 页面命中

    • 如果页面已经在内存中,更新该页面的时间戳为当前的全局时钟值。

  4. 页面缺失

    • 如果页面不在内存中,需要进行页面置换。

    • 遍历所有在内存中的页面,找到具有最小时间戳的页面,即最长时间未被访问的页面。

  5. 页面置换

    • 将选中的页面从内存中移除,并将新页面加载到该页框中。

    • 更新新页面的时间戳为当前的全局时钟值。

  6. 更新全局时钟

    • 每次页面访问后,无论是否发生页面置换,都递增全局时钟值。

  7. 评估性能

    • 计算缺页次数,评估页面置换算法的性能。

图中案例分析

在图中的案例中,我们有3个页框,页面引用序列为 ABCABDADBCBCB。以下是使用时间戳实现LRU算法的具体步骤:

  1. 开始时,内存为空,时间戳表也为空。

  2. 引用 A 时,将 A 放入第一个页框,时间戳设为1。

  3. 引用 B 时,将 B 放入第二个页框,时间戳设为2。

  4. 引用 C 时,将 C 放入第三个页框,时间戳设为3。

  5. 再次引用 A 时,更新 A 的时间戳为4(页面命中)。

  6. 引用 B 时,更新 B 的时间戳为5(页面命中)。

  7. 引用 D 时,需要进行页面置换。此时,C 的时间戳最小(3),因此选择 C 进行淘汰,将 D 放入第三个页框,时间戳设为6。

  8. 引用 A 时,更新 A 的时间戳为7(页面命中)。

  9. 引用 D 时,更新 D 的时间戳为8(页面命中)。

  10. 引用 B 时,更新 B 的时间戳为9(页面命中)。

  11. 引用 C 时,需要进行页面置换。此时,A 的时间戳最小(4),因此选择 A 进行淘汰,将 C 放入第一个页框,时间戳设为10。

  12. 引用 B 时,更新 B 的时间戳为11(页面命中)。

在这个过程中,总共发生了5次缺页。

难实现!!!

页码栈实现

图中展示了如何使用页码栈来实现LRU(最近最少使用)页面置换算法。这种方法通过维护一个栈(或队列)来跟踪页面的使用顺序。当需要进行页面置换时,选择栈底的页面进行淘汰,即该页面是最近最少使用的。

实现步骤

  1. 初始化

    • 创建一个栈,用于存储当前在内存中的页面。

    • 初始化一个映射(如哈希表),用于快速查找页面在栈中的位置。

  2. 页面引用

    • 当程序引用一个页面时,系统检查该页面是否已经在内存中。

  3. 页面命中

    • 如果页面已经在内存中,将该页面移到栈顶(表示最近被访问过)。

  4. 页面缺失

    • 如果页面不在内存中,需要进行页面置换。

    • 选择栈底的页面进行淘汰(最长时间未被访问的页面)。

  5. 页面置换

    • 将选中的页面从栈中移除,并将新页面加载到栈顶。

  6. 更新映射

    • 更新映射,以反映新页面在栈中的位置。

  7. 评估性能

    • 计算缺页次数,评估页面置换算法的性能。

图中案例分析

在图中的案例中,我们有3个页框,页面引用序列为 ABCABDADBCBCB。以下是使用页码栈实现LRU算法的具体步骤:

  1. 开始时,栈为空。

  2. 引用 A 时,将 A 压入栈顶。

  3. 引用 B 时,将 B 压入栈顶。

  4. 引用 C 时,将 C 压入栈顶。

  5. 再次引用 A 时,将 A 从栈中移出并重新压入栈顶(页面命中)。

  6. 引用 B 时,将 B 从栈中移出并重新压入栈顶(页面命中)。

  7. 引用 D 时,需要进行页面置换。此时,栈底是 C,因此选择 C 进行淘汰,将 D 压入栈顶。

  8. 引用 A 时,将 A 从栈中移出并重新压入栈顶(页面命中)。

  9. 引用 D 时,将 D 从栈中移出并重新压入栈顶(页面命中)。

  10. 引用 B 时,将 B 从栈中移出并重新压入栈顶(页面命中)。

  11. 引用 C 时,需要进行页面置换。此时,栈底是 A,因此选择 A 进行淘汰,将 C 压入栈顶。

  12. 引用 B 时,将 B 从栈中移出并重新压入栈顶(页面命中)。

在这个过程中,总共发生了5次缺页。

难实现!!!

SCR

图中展示的是Clock算法,也称为Second Chance算法,这是一种近似实现LRU(最近最少使用)页面置换策略的方法。它通过给每个页面添加一个引用位(reference bit)来模拟时间戳,从而实现页面的置换决策。这种方法比维护全局时间戳或页码栈的实现方式要简单,且实现代价较小。

Clock算法实现步骤

  1. 初始化

    • 为每个页框分配一个引用位(通常为一个二进制位),初始值设为0。

    • 创建一个指针(或称为“时钟指针”),用于扫描页框。

  2. 页面引用

    • 当程序引用一个页面时,系统检查该页面是否已经在内存中。

    • 如果页面命中,硬件自动将该页面的引用位设置为1。

  3. 页面缺失

    • 如果页面不在内存中(页面缺失),时钟指针开始扫描页框。

    • 扫描过程中,如果遇到引用位为1的页面,将其引用位清0,并继续扫描下一个页面。

    • 如果遇到引用位为0的页面,选择该页面进行淘汰,并加载新页面到该页框中。

  4. 更新引用位

    • 当新页面加载到页框后,将其引用位设置为1。

  5. 循环扫描

    • 如果在一轮扫描中没有找到引用位为0的页面(即所有页面的引用位都被设置为1),则选择第一个引用位为1的页面进行淘汰,并重新设置其引用位为0。

    • 如果遇到引用位为0的页面,淘汰。

  6. 评估性能

    • 计算缺页次数,评估页面置换算法的性能。

图中案例分析

图中展示了Clock算法的工作流程,其中每个页框都有一个引用位(R=0或R=1)。以下是具体步骤:

  1. 开始时,所有引用位都设置为0。

  2. 当访问页面时,硬件自动将对应的引用位设置为1。

  3. 当需要置换页面时,时钟指针开始扫描页框。

  4. 在扫描过程中,如果遇到引用位为1的页面,将其引用位清0,并继续扫描

  5. 如果遇到引用位为0的页面,选择该页面进行淘汰,并加载新页面到该页框中,同时将新页面的引用位设置为1。

  6. 如果在一轮扫描中没有找到引用位为0的页面(即所有页面的引用位都被设置为1),则选择第一个引用位为1的页面进行淘汰,并重新设置其引用位为0

Clock算法改造优化

问题描述

  1. 缺页很少时的情况

    • 如果系统中的缺页很少,可能会导致所有页面的引用位(R位)都被设置为1。这种情况下,Clock算法可能会退化为FIFO算法,因为它会不断地扫描直到找到一个可以替换的页面。

  2. 记录太长的历史信息

    • 如果系统中的页面长时间没有被替换,它们的引用位可能会一直保持为1,这会导致算法效率降低,因为它需要扫描更多的页面来找到一个R位为0的页面。

改造建议:

  1. 定时清除R位

    • 为了解决R位长时间为1的问题,可以定时清除所有页面的R位。这样可以确保算法不会记住太长的历史信息,从而避免退化为FIFO算法。

  2. 使用两个扫描指针

    • 引入一个快速移动的扫描指针用于清除R位,一个慢速移动的扫描指针用于选择淘汰页面。这样可以提高清除R位的效率,同时保持选择淘汰页面的准确性。

实现步骤:

  1. 初始化

    • 为每个页框分配一个引用位(R位),初始值设为0。

    • 创建两个扫描指针,一个用于清除R位(快速移动),一个用于选择淘汰页面(慢速移动)。

  2. 页面引用

    • 当程序引用一个页面时,将该页面的R位设置为1。

  3. 页面缺失

    • 如果页面不在内存中,慢速扫描指针开始扫描页框以选择淘汰页面。

    • 如果遇到R位为1的页面,将其R位清0,并继续扫描。

    • 如果遇到R位为0的页面,选择该页面进行淘汰,并加载新页面到该页框中,同时将新页面的R位设置为1。

  4. 清除R位

    • 快速扫描指针周期性地扫描所有页框,将所有页面的R位清0。

  5. 更新扫描指针

    • 每次页面置换后,慢速扫描指针前移一位。

    • 快速扫描指针在清除完所有R位后也前移一位。

  6. 评估性能

    • 计算缺页次数,评估页面置换算法的性能。

给进程分配多少页框

分配页框的挑战:

  1. 分配过多

    • 如果给每个进程分配过多的页框,虽然可以减少缺页率,提高内存的高效利用,但这样做会减少系统中可用的页框总数,导致无法同时运行更多的进程。

  2. 分配过少

    • 如果分配的页框太少,每个进程的缺页率会增大,导致更多的页面置换操作,从而增加进程等待调页完成的时间,降低CPU利用率。

颠簸(Thrashing)现象:

  • 定义:颠簸是指系统因为进程的缺页率过高,导致大部分时间都在进行页面置换操作,而实际的CPU利用率却很低的现象。

  • 原因:当系统中进程数量过多时,每个进程分配到的页框数量减少,导致缺页率增加。随着缺页率的增加,进程需要花费更多的时间等待页面置换完成,从而减少了CPU的有效工作时间。

  • 影响:颠簸会导致系统性能急剧下降,因为CPU大部分时间都在处理页面置换,而不是执行用户进程。

图中现象分析:

图中展示了CPU利用率与多道程序程度(即系统中同时运行的进程数量)之间的关系。随着进程数量的增加,CPU利用率先增加后减少,形成一个峰值。这个峰值之后,CPU利用率急剧下降,这就是颠簸现象。

解决策略:

  1. 合理分配页框

    • 需要找到一个平衡点,即合理分配页框数量,使得系统中的进程既能有效利用内存,又不至于因为缺页率过高而导致颠簸。

通过这些策略,可以有效地避免颠簸现象,提高系统的稳定性和性能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2333124.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Amazon EC2】为何基于浏览器的EC2 Instance Connect 客户端连接不上EC2实例

文章目录 前言📖一、报错先知❌二、问题复现😯三、解决办法🎲四、验证结果👍五、参考链接🔗 前言📖 这篇文章将讲述我在 Amazon EC2 上使用 RHEL9 AMI 时无法连接到 EC2 实例时所遇到的麻烦😖 …

新一代AI低代码MES,助力企业数字化升级

随着DeepSeek低成本AI模型的火热,对于传统的MES而言,在这场AI的盛宴中,该如何去调整产品的定位,让MES更符合工业企业的需求呢? 工业互联网、AI、数字孪生等技术加速与MES融合,实现生产全流程的实时监控与智…

HTML应用指南:利用GET请求获取全国汉堡王门店位置信息

在当今快节奏的都市生活中,餐饮品牌的门店布局不仅反映了其市场策略,更折射出消费者对便捷、品质和品牌认同的追求。汉堡王(Burger King)作为全球知名的西式快餐品牌之一,在中国市场同样占据重要地位。自进入中国市场以…

AICon 2024年全球人工智能与大模型开发与应用大会(脱敏)PPT汇总(36份).zip

AICon 2024年全球人工智能与大模型开发与应用大会(脱敏)PPT汇总(36份).zip 1、面向开放域的大模型智能体.pdf 2、企业一站式 AI 智能体构建平台演进实践.pdf 3、PPIO 模型平台出海实战,跨地域业务扩展中的技术优化之道…

51电子表

设计要求: 基本任务: 用单片机和数码管设计可调式电子钟,采用24小时制计时方式,要求能够稳定准确计时,并能调整时间。发光二极管每秒亮灭一次。电子钟显示格式为:时、分、秒各两位,中间有分隔…

9-函数的定义及用法

一.前言 C 语⾔强调模块化编程,这⾥所说的模块就是函数,即把每⼀个独⽴的功能均抽象为⼀个函数来实现。从⼀定意义上讲,C 语⾔就是由⼀系列函数串组成的。 我们之前把所有代码都写在 main 函数中,这样虽然程序的功能正常实现&…

用HTML和CSS绘制佩奇:我不是佩奇

在这篇博客中,我将解析一个完全使用HTML和CSS绘制的佩奇(Pig)形象。这个项目展示了CSS的强大能力,仅用样式就能创造出复杂的图形,而不需要任何图片或JavaScript。 项目概述 这个名为"我不是佩奇"的项目是一个纯CSS绘制的卡通猪形象…

彩讯携Rich AICloud与一体机智算解决方案亮相中国移动云智算大会

2025年4月10日,2025中国移动云智算大会在苏州盛大开幕,本次大会以“由云向智 共绘算网新生态”为主题,与会嘉宾围绕算力展开重点探讨。 大会现场特设区域展出各参会单位的最新算力成果,作为中国移动重要合作伙伴,彩讯…

声学测温度原理解释

已知声速,就可以得到温度。 不同温度下的胜诉不同。 25度的声速大约346m/s 绝对温度-273度 不同温度下的声速。 FPGA 通过测距雷达测温度,固定测量距离,或者可以测出当前距离。已知距离,然后雷达发出声波到接收到回波的时间&a…

Cuto壁纸 2.6.9 | 解锁所有高清精选壁纸,无广告干扰

Cuto壁纸 App 提供丰富多样的壁纸选择,涵盖动物、风景、创意及游戏动漫等类型。支持分类查找与下载,用户可轻松将心仪壁纸设为手机背景,并享受软件内置的编辑功能调整尺寸。每天更新,确保用户总能找到新鲜、满意的壁纸。 大小&am…

C语言 AI 通义灵码 VSCode插件安装与功能详解

在 C 语言开发领域,一款高效的编码助手能够显著提升开发效率和代码质量。 通义灵码,作为阿里云技术团队打造的智能编码助手,凭借其强大的功能,正逐渐成为 C 语言开发者的新宠。 本文将深入探讨通义灵码在 C 语言开发中的应用&am…

二分查找5:852. 山脉数组的峰顶索引

链接:852. 山脉数组的峰顶索引 - 力扣(LeetCode) 题解: 事实证明,二分查找不局限于有序数组,非有序的数组也同样适用 二分查找主要思想在于二段性,即将数组分为两段。本体就可以将数组分为ar…

【模拟电路】稳压二极管/齐纳二极管

齐纳二极管也被称为稳压二极管,是一种特殊的二极管,其工作原理是利用PN结的反向击穿状态。在齐纳二极管中,当反向电压增加到一定程度,即达到齐纳二极管的击穿电压时,反向电流会急剧增加,但此时齐纳二极管的电压却基本保持不变。这种特性使得齐纳二极管可以作为稳压器或电…

项目周期过长,如何拆分里程碑

应对项目周期过长,合理拆分里程碑需要做到:明确项目整体目标与阶段目标、合理进行任务细分与分组、设定阶段性里程碑节点、实施有效的进度跟踪与反馈机制、灵活进行里程碑调整。其中,明确项目整体目标与阶段目标尤为关键。这能够帮助团队在长…

蓝桥杯刷题总结 + 应赛技巧

当各位小伙伴们看到这篇文章的时候想必蓝桥杯也快开赛了,那么本篇文章博主就来总结一下一些蓝桥杯的应赛技巧,那么依旧先来走个流程 那么接下来我们分成几个板块进行总结 首先是一些基本语法 编程语言的基本语法 首先是数组,在存数据的时候…

希哈表的学习

#include <stdio.h> #include <stdlib.h> #include "uthash.h"typedef struct {int id; // 学号&#xff0c;作为keychar name[20]; // 姓名&#xff0c;作为valueUT_hash_handle hh; // 必须有这个字段 } Student;Student* studen…

Qt之OpenGL使用Qt封装好的着色器和编译器

代码 #include "sunopengl.h"sunOpengl::sunOpengl(QWidget *parent) {}unsigned int VBO,VAO; float vertices[]{0.5f,0.5f,0.0f,0.5f,-0.5f,0.0f,-0.5f,-0.5f,0.0f,-0.5f,0.5f,0.0f };unsigned int indices[]{0,1,3,1,2,3, }; unsigned int EBO; sunOpengl::~sunO…

零基础开始学习鸿蒙开发-智能家居APP离线版介绍

目录 1.我的小屋 2.查找设备 3.个人主页 前言 好久不发博文了&#xff0c;最近都忙于面试&#xff0c;忙于找工作&#xff0c;这段时间终于找到工作了。我对鸿蒙开发的激情依然没有减退&#xff0c;前几天做了一个鸿蒙的APP&#xff0c;现在给大家分享一下&#xff01; 具体…

不再卡顿!如何根据使用需求挑选合适的电脑内存?

电脑运行内存多大合适&#xff1f;在选购或升级电脑时&#xff0c;除了关注处理器的速度、硬盘的容量之外&#xff0c;内存&#xff08;RAM&#xff09;的大小也是决定电脑性能的一个重要因素。但究竟电脑运行内存多大才合适呢&#xff1f;这篇文章将帮助你理解不同使用场景下适…

华为云 云化数据中心 CloudDC | 架构分析与应用场景

云化数据中心 CloudDC 云化数据中心 (CloudDC)是一种满足传统DC客户云化转型诉求的产品&#xff0c;支持将客户持有服务器设备部署至华为云机房&#xff0c;通过外溢华为云的基础设施管理、云化网络、裸机纳管、确定性运维等能力&#xff0c;帮助客户DC快速云化转型。 云化数据…