FIFO和LRU算法实现操作系统中主存管理

FIFO,用数组实现

1和2都是使用nextReplace实现新页面位置的更新

1、不精确时间:用ctime输出运行时间都是0.00秒

#include <iostream>
#include <iomanip>
#include<ctime>//用于计算时间
using namespace std;// 页访问顺序
int pages[20] = { 7, 0, 1, 2, 0, 3, 0, 4, 2, 3, 0, 3, 2, 1, 2, 0, 1, 7, 0, 1 };// FIFO算法
void fifo(int n) {int memory[5] = { -1, -1, -1, -1, -1 };  // 用于存储主存块,初始化为 -1 表示空int table[5][20] = { -1 };               // 用于记录每次访问的内存状态,初始化为 -1 表示空bool status[20];                         // 记录是否缺页int pageFaults = 0;                      // 缺页次数int nextReplace = 0;                     // 记录下一个要替换的位置// 获取开始时间(时钟周期数)clock_t start = clock();// 遍历每个页面访问for (int j = 0; j < 20; j++) {int page = pages[j];bool found = false;// 检查页面是否已在内存中for (int i = 0; i < n; i++) {if (memory[i] == page) {found = true;break;}}if (!found) {  // 缺页情况memory[nextReplace] = page;       // 替换页面nextReplace = (nextReplace + 1) % n; // 更新替换位置status[j] = false;                // 标记缺页pageFaults++;}else {status[j] = true;                 // 标记命中}// 记录当前内存状态到表格for (int i = 0; i < n; i++) {table[i][j] = memory[i];}}// 获取结束时间(时钟周期数)clock_t end = clock();// 输出结果表格cout << "主存块号 ";for (int j = 0; j < 20; j++) {cout << pages[j] << " ";}cout << endl;for (int i = 0; i < n; i++) {cout << "   " << i << "     ";for (int j = 0; j < 20; j++) {if (table[i][j] == -1) {cout << "  ";  // 空块显示为空格}else {cout << table[i][j] << " ";}}cout << endl;}// 输出缺页标记cout << "是否缺页 ";for (int j = 0; j < 20; j++) {if (status[j]) {cout << "\u221A ";  // Unicode "√"}else {cout << "\u00D7 ";  // Unicode "×"}}cout << endl;cout << "FIFO 缺页率: " << fixed << setprecision(2) << (float)pageFaults / 20 * 100 << "%" << endl;cout << "运行时间: " << (double)(end - start) / CLOCKS_PER_SEC << " 秒" << endl; // 输出运行时间
}int main() {cout << "内存容量为 3 块:\n";fifo(3);cout << endl;cout << "内存容量为 4 块:\n";fifo(4);return 0;
}

2、精确时间:用chrono输出运行时间都是xx微秒,输出时间不定

#include <iostream>
#include <iomanip>
#include <chrono> // 引入chrono库using namespace std;
using namespace std::chrono; // 使用chrono命名空间// 页访问顺序
int pages[20] = { 7, 0, 1, 2, 0, 3, 0, 4, 2, 3, 0, 3, 2, 1, 2, 0, 1, 7, 0, 1 };// FIFO算法
void fifo(int n) {int memory[5] = { -1, -1, -1, -1, -1 };  // 用于存储主存块,初始化为 -1 表示空int table[5][20] = { -1 };               // 用于记录每次访问的内存状态,初始化为 -1 表示空bool status[20];                         // 记录是否缺页int pageFaults = 0;                      // 缺页次数int nextReplace = 0;                     // 记录下一个要替换的位置// 获取开始时间auto start = high_resolution_clock::now();// 遍历每个页面访问for (int j = 0; j < 20; j++) {int page = pages[j];bool found = false;// 检查页面是否已在内存中for (int i = 0; i < n; i++) {if (memory[i] == page) {found = true;break;}}if (!found) {  // 缺页情况memory[nextReplace] = page;       // 替换页面nextReplace = (nextReplace + 1) % n; // 更新替换位置status[j] = false;                // 标记缺页pageFaults++;}else {status[j] = true;                 // 标记命中}// 记录当前内存状态到表格for (int i = 0; i < n; i++) {table[i][j] = memory[i];}}// 获取结束时间auto stop = high_resolution_clock::now();auto duration = duration_cast<microseconds>(stop - start);// 输出结果表格cout << "主存块号 ";for (int j = 0; j < 20; j++) {cout << pages[j] << " ";}cout << endl;for (int i = 0; i < n; i++) {cout << "   " << i << "     ";for (int j = 0; j < 20; j++) {if (table[i][j] == -1) {cout << "  ";  // 空块显示为空格}else {cout << table[i][j] << " ";}}cout << endl;}// 输出缺页标记cout << "是否缺页 ";for (int j = 0; j < 20; j++) {if (status[j]) {cout << "\u221A ";  // Unicode "√"}else {cout << "\u00D7 ";  // Unicode "×"}}cout << endl;cout << "FIFO 缺页率: " << fixed << setprecision(2) << (float)pageFaults / 20 * 100 << "%" << endl;cout << "运行时间: " << duration.count() << " 微秒" << endl; // 输出运行时间
}int main() {cout << "内存容量为 3 块:\n";fifo(3);cout << endl;cout << "内存容量为 4 块:\n";fifo(4);return 0;
}

3、数组模拟队列、类似滑动窗口

#include <iostream>
#include <iomanip>
#include <chrono>
#include <cstring>using namespace std;
using namespace std::chrono;const int N = 1010;
int memory[N];//每次查找页面进行记录的滑动窗口
int table[5][20]; // 最终输出的表格状态
// 页访问顺序
int pages[20] = { 7, 0, 1, 2, 0, 3, 0, 4, 2, 3, 0, 3, 2, 1, 2, 0, 1, 7, 0, 1 };// FIFO算法
void fifo(int n) {memset(memory, 0x3f, sizeof memory);bool status[20];  // 记录是否缺页int pageFaults = 0;       // 缺页次数int hh = 0, tt = -1;      // 队首和队尾指针auto start = high_resolution_clock::now(); // 获取开始时间for (int j = 0; j < 20; j++) {int page = pages[j];bool found = false;// 检查页面是否已在内存中for (int i = hh; i <= tt; i++) {if (memory[i] == page) {found = true;break;}}if (!found) {  // 缺页情况memory[++tt] = page; // 新页面加入队尾// 控制滑动窗口大小为 nif (tt - hh + 1 > n) {hh++; // 超过容量,队首出队}status[j] = false;  // 标记缺页pageFaults++;}else {status[j] = true;   // 标记命中}// 记录当前内存状态到表格for (int i = 0; i < n; i++) {//如果只写memory[hh]的话不就移动队首指针了吗,不可以,现在是赋值阶段,只需要控制负责赋值的滑动指针首先不能超过队尾指针,确保在滑动窗口范围内,//因为有可能这个滑动窗口不足n长,你就会多余赋值本来不能存在的页面号赋值成0x3f,其次需要满足当前检查是否缺页的一次记录memory,该位置是否有值if (i + hh <= tt && memory[i + hh] != 0x3f) {table[i][j] = memory[i + hh];}else {table[i][j] = -1; // 空位显示为 -1}}}auto stop = high_resolution_clock::now(); // 获取结束时间auto duration = duration_cast<microseconds>(stop - start);// 输出结果表格cout << "主存块号 ";for (int j = 0; j < 20; j++) {cout << pages[j] << " ";}cout << endl;for (int i = 0; i < n; i++) {cout << "   " << i << "     ";for (int j = 0; j < 20; j++) {if (table[i][j] == -1) {cout << "  ";  // 空块显示为空格}else {cout << table[i][j] << " ";}}cout << endl;}// 输出缺页标记cout << "是否缺页 ";for (int j = 0; j < 20; j++) {cout << (status[j] ? "\u221A " : "\u00D7 ");//unicode编码,前者代表true则不缺页是√标识,后者代表false是缺页×表示}cout << endl;cout << "FIFO 缺页率: " << fixed << setprecision(2) << (float)pageFaults / 20 * 100 << "%" << endl;cout << "运行时间: " << duration.count() << " 微秒" << endl;
}int main() {cout << "内存容量为 3 块:\n";fifo(3);cout << endl;cout << "内存容量为 4 块:\n";fifo(4);return 0;
}

朴素版算缺页率

#include <iostream>
#include <ctime>
#include <cstring>using namespace std;const int N = 1010;
int memory[N];//每次查找页面进行记录的滑动窗口
int table[5][20]; // 最终输出的表格状态
// 页访问顺序
int pages[20] = { 7, 0, 1, 2, 0, 3, 0, 4, 2, 3, 0, 3, 2, 1, 2, 0, 1, 7, 0, 1 };// FIFO算法
void fifo(int n) {memset(memory, 0x3f, sizeof memory);bool status[20];  // 记录是否缺页int pageFaults = 0;       // 缺页次数int hh = 0, tt = -1;      // 队首和队尾指针clock_t start=clock(); // 获取开始时间for (int j = 0; j < 20; j++) {int page = pages[j];bool found = false;// 检查页面是否已在内存中for (int i = hh; i <= tt; i++) {if (memory[i] == page) {found = true;break;}}if (!found) {  // 缺页情况memory[++tt] = page; // 新页面加入队尾// 控制滑动窗口大小为 nif (tt - hh + 1 > n) {hh++; // 超过容量,队首出队}status[j] = false;  // 标记缺页pageFaults++;}else {status[j] = true;   // 标记命中}// 记录当前内存状态到表格for (int i = 0; i < n; i++) {//如果只写memory[hh]的话不就移动队首指针了吗,不可以,现在是赋值阶段,只需要控制负责赋值的滑动指针首先不能超过队尾指针,确保在滑动窗口范围内,//因为有可能这个滑动窗口不足n长,你就会多余赋值本来不能存在的页面号赋值成0x3f,其次需要满足当前检查是否缺页的一次记录memory,该位置是否有值if (i + hh <= tt && memory[i + hh] != 0x3f) {table[i][j] = memory[i + hh];}else {table[i][j] = -1; // 空位显示为 -1}}}clock_t end = clock(); // 获取结束时间// 输出结果表格cout << "主存块号 ";for (int j = 0; j < 20; j++) {cout << pages[j] << " ";}cout << endl;for (int i = 0; i < n; i++) {cout << "   " << i << "     ";for (int j = 0; j < 20; j++) {if (table[i][j] == -1) {cout << "  ";  // 空块显示为空格}else {cout << table[i][j] << " ";}}cout << endl;}// 输出缺页标记cout << "是否缺页 ";for (int j = 0; j < 20; j++) {cout << (status[j] ? "\u221A " : "\u00D7 ");//unicode编码,前者代表true则不缺页是√标识,后者代表false是缺页×表示}cout << endl;cout << "FIFO 缺页率: " << (float)pageFaults / 20 * 100 << "%" << endl;cout << "运行时间: " << (double)(end-start)/CLOCKS_PER_SEC << " 秒" << endl;}int main() {cout << "内存容量为 3 块:\n";fifo(3);cout << endl;cout << "内存容量为 4 块:\n";fifo(4);return 0;
}

FIFO,用链表实现

LRU,用计数器实现

#include <iostream>
#include <ctime>
#include <cstring>
#include <unordered_map>using namespace std;const int N = 1010;
int table[5][20]; // 最终输出的表格状态
unordered_map<int, int> m; // 键为page号,值为count值
int pages[20] = { 7, 0, 1, 2, 0, 3, 0, 4, 2, 3, 0, 3, 2, 1, 2, 0, 1, 7, 0, 1 };void lru(int n) {memset(table, -1, sizeof table);m.clear();bool status[20]; // 记录是否缺页int pageFaults = 0; // 缺页次数clock_t start = clock(); // 获取开始时间for (int j = 0; j < 20; j++) {int page = pages[j];if (!m.count(page)) { // 没命中就要加入或者替换页面if (m.size() >= n) {// 找到count最大的页面进行替换int maxpage = -1, maxcounts = -1;for (auto p : m) {if (p.second > maxcounts) {maxpage = p.first;maxcounts = p.second;}}m.erase(maxpage);}m[page] = 0;//没命中且主存没满则直接加入页面pageFaults++;status[j] = false; // 标记缺页}else {status[j] = true; // 标记命中m[page] = 0;}// 更新所有页面的count值:命中则置0,没命中加入新页面——满足条件则不加1即可,不管加不加入新页面,其他没中的页面都是要count+1的for (auto& p : m) {if (p.first != page) {p.second += 1;}}// 更新当前主存块内存在的页面int i = 0;for (auto p : m) {if (i < n) {//用一个i去便利贮存块,而不用fortable[i][j] = p.first;i++;}}//一开始写错了:/*for (int i = 0; i < n; i++) {for (auto p : m) {table[i][j] = p.first;}}*/}clock_t end = clock(); // 获取结束时间// 输出结果表格cout << "主存块号 ";for (int j = 0; j < 20; j++) {cout << pages[j] << " ";}cout << endl;for (int i = 0; i < n; i++) {cout << "   " << i << "     ";for (int j = 0; j < 20; j++) {if (table[i][j] == -1) {cout << "  "; // 空块显示为空格}else {cout << table[i][j] << " ";}}cout << endl;}// 输出缺页标记cout << "是否缺页 ";for (int j = 0; j < 20; j++) {cout << (status[j] ? "\u221A " : "\u00D7 ");}cout << endl;cout << "LRU 缺页率: " << (float)(pageFaults) / 20 * 100 << "%" << endl;cout << "运行时间: " << (double)(end - start) / CLOCKS_PER_SEC << " 秒" << endl;
}int main() {cout << "内存容量为 3 块:\n";lru(3);cout << endl;cout << "内存容量为 4 块:\n";lru(4);return 0;
}

LRU,用堆栈实现

两个算法综合在一起看运行速率

#include <iostream>
#include <ctime>
#include <cstring>
#include <unordered_map>
#include <chrono> // 引入chrono库using namespace std;
using namespace std::chrono; // 使用chrono命名空间const int N = 1010;
int table[5][20]; // 最终输出的表格状态
unordered_map<int, int> m; // 键为page号,值为count值
int pages[20] = { 7, 0, 1, 2, 0, 3, 0, 4, 2, 3, 0, 3, 2, 1, 2, 0, 1, 7, 0, 1 };
int memory[N];//每次查找页面进行记录的滑动窗口// FIFO算法
void fifo(int n) {memset(memory, 0x3f, sizeof memory);memset(table, -1, sizeof table);bool status[20];  // 记录是否缺页int pageFaults = 0;       // 缺页次数int hh = 0, tt = -1;      // 队首和队尾指针//clock_t start = clock(); // 获取开始时间// 获取开始时间auto start = high_resolution_clock::now();for (int j = 0; j < 20; j++) {int page = pages[j];bool found = false;// 检查页面是否已在内存中for (int i = hh; i <= tt; i++) {if (memory[i] == page) {found = true;break;}}if (!found) {  // 缺页情况memory[++tt] = page; // 新页面加入队尾// 控制滑动窗口大小为 nif (tt - hh + 1 > n) {hh++; // 超过容量,队首出队}status[j] = false;  // 标记缺页pageFaults++;}else {status[j] = true;   // 标记命中}// 记录当前内存状态到表格for (int i = 0; i < n; i++) {//如果只写memory[hh]的话不就移动队首指针了吗,不可以,现在是赋值阶段,只需要控制负责赋值的滑动指针首先不能超过队尾指针,确保在滑动窗口范围内,//因为有可能这个滑动窗口不足n长,你就会多余赋值本来不能存在的页面号赋值成0x3f,其次需要满足当前检查是否缺页的一次记录memory,该位置是否有值if (i + hh <= tt && memory[i + hh] != 0x3f) {table[i][j] = memory[i + hh];}else {table[i][j] = -1; // 空位显示为 -1}}}//clock_t end = clock(); // 获取结束时间// 获取结束时间auto stop = high_resolution_clock::now();auto duration = duration_cast<microseconds>(stop - start);// 输出结果表格cout << "主存块号 ";for (int j = 0; j < 20; j++) {cout << pages[j] << " ";}cout << endl;for (int i = 0; i < n; i++) {cout << "   " << i << "     ";for (int j = 0; j < 20; j++) {if (table[i][j] == -1) {cout << "  ";  // 空块显示为空格}else {cout << table[i][j] << " ";}}cout << endl;}// 输出缺页标记cout << "是否缺页 ";for (int j = 0; j < 20; j++) {cout << (status[j] ? "\u221A " : "\u00D7 ");//unicode编码,前者代表true则不缺页是√标识,后者代表false是缺页×表示}cout << endl;cout << "FIFO 缺页率: " << (float)pageFaults / 20 * 100 << "%" << endl;//cout << "运行时间: " << (double)(end - start) / CLOCKS_PER_SEC << " 秒" << endl;cout << "运行时间: " << duration.count() << " 微秒" << endl; // 输出运行时间}
void lru(int n) {memset(table, -1, sizeof table);m.clear();bool status[20]; // 记录是否缺页int pageFaults = 0; // 缺页次数//clock_t start = clock(); // 获取开始时间// 获取开始时间auto start = high_resolution_clock::now();for (int j = 0; j < 20; j++) {int page = pages[j];if (!m.count(page)) { // 没命中就要加入或者替换页面if (m.size() >= n) {// 找到count最大的页面进行替换int maxpage = -1, maxcounts = -1;for (auto p : m) {if (p.second > maxcounts) {maxpage = p.first;maxcounts = p.second;}}m.erase(maxpage);}m[page] = 0;//没命中且主存没满则直接加入页面pageFaults++;status[j] = false; // 标记缺页}else {status[j] = true; // 标记命中m[page] = 0;}// 更新所有页面的count值:命中则置0,没命中加入新页面——满足条件则不加1即可,不管加不加入新页面,其他没中的页面都是要count+1的for (auto& p : m) {if (p.first != page) {p.second += 1;}}// 更新当前主存块内存在的页面int i = 0;for (auto p : m) {if (i < n) {//用一个i去便利贮存块,而不用fortable[i][j] = p.first;i++;}}//一开始写错了:/*for (int i = 0; i < n; i++) {for (auto p : m) {table[i][j] = p.first;}}*/}//clock_t end = clock(); // 获取结束时间// 获取结束时间auto stop = high_resolution_clock::now();auto duration = duration_cast<microseconds>(stop - start);// 输出结果表格cout << "主存块号 ";for (int j = 0; j < 20; j++) {cout << pages[j] << " ";}cout << endl;for (int i = 0; i < n; i++) {cout << "   " << i << "     ";for (int j = 0; j < 20; j++) {if (table[i][j] == -1) {cout << "  "; // 空块显示为空格}else {cout << table[i][j] << " ";}}cout << endl;}// 输出缺页标记cout << "是否缺页 ";for (int j = 0; j < 20; j++) {cout << (status[j] ? "\u221A " : "\u00D7 ");}cout << endl;cout << "LRU 缺页率: " << (float)(pageFaults) / 20 * 100 << "%" << endl;//cout << "运行时间: " << (double)(end - start) / CLOCKS_PER_SEC << " 秒" << endl;cout << "运行时间: " << duration.count() << " 微秒" << endl; // 输出运行时间
}int main() {cout << "内存容量为 3 块:\n";fifo(3);cout << endl;lru(3);cout << endl;cout << "内存容量为 4 块:\n";fifo(4);cout << endl;lru(4);return 0;
}

1)主存块数越多的,不论哪个算法,运行时间都更长一些,用的时chrono精确时间微妙

但是同样的,运行每次的时间不定

2)主存块数越多的,不论哪个算法,缺页率都更低一些

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

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

相关文章

ssm161基于web的资源共享平台的共享与开发+jsp(论文+源码)_kaic

毕 业 设 计&#xff08;论 文&#xff09; 题目&#xff1a;资源共享平台设计与实现 摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本资源共享平台就是在…

LeetCode 力扣 热题 100道(六)合并两个有序链表(C++)

合并两个有序链表 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 输入&#xff1a;l1 [1,2,4], l2 [1,3,4] 输出&#xff1a;[1,1,2,3,4,4]示例 2&#xff1a; 输入&#xff1a;l1 [], l2 [] 输出&#xff1a;[]示…

ubuntu显示管理器_显示导航栏

ubuntu文件管理器_显示导航栏 一、原始状态&#xff1a; 二、显示导航栏状态&#xff1a; 三、原始状态--->导航栏状态: 1、打开dconf编辑器&#xff0c;直接在搜索栏搜索 dconf-editor ------如果没有安装&#xff0c;直接按流程安装即可。 2、进入目录&#xff1a;org …

高集成的MCU方案已成电机应用趋势?

【哔哥哔特导读】高集成化的芯片成为当下MCU领域研发和市场布局的重点&#xff0c;但是在实际应用中仍然面临散热等痛点问题&#xff0c;MCU厂商是如何解决和优化这些痛点&#xff1f; 随着全球工业自动化、智能制造和绿色发展的不断推进&#xff0c;中国电机行业正站在新一轮…

购物街项目TabBar的封装

1.TabBar介绍 在购物街项目中 不论页面如何滚动 始终存在一个TabBar固定在该项目的底部 他在该项目中 扮演者选项卡栏的角色 内部存在若干选项 而选项中 固定存在两部分(图片文本) 其中主要涉及到TabBar/TabBarItem这些和业务无关的共享组件(建议存放于components/common中)、…

优化表单交互:在 el-select 组件中嵌入表格显示选项

介绍了一种通过 el-select 插槽实现表格样式数据展示的方案&#xff0c;可更直观地辅助用户选择。支持列配置、行数据绑定及自定义搜索&#xff0c;简洁高效&#xff0c;适用于复杂选择场景。完整代码见GitHub 仓库。 背景 在进行业务开发选择订单时&#xff0c;如果单纯的根…

最新Kali安装详细版教程(附安装包,傻瓜式安装教程)

本文主要详细介绍 kali 的安装过程&#xff0c;以及安装完成后的基本设置&#xff0c;比如安装增强工具&#xff0c;安装中文输入法以及更新升级等操作。 文章目录 实验环境准备工作步骤说明安装虚拟机安装 Kali安装增强工具安装中文输入法更新升级 实验环境 VMware &#x…

细说STM32单片机DMA中断收发RTC实时时间并改善其鲁棒性的方法

目录 一、DMA基础知识 1、DMA简介 (1)DMA控制器 (2)DMA流 (3)DMA请求 (4)仲裁器 (5)DMA传输属性 2、源地址和目标地址 3、DMA传输模式 4、传输数据量的大小 5、数据宽度 6、地址指针递增 7、DMA工作模式 8、DMA流的优先级别 9、FIFO或直接模式 10、单次传输或突…

H.265流媒体播放器EasyPlayer.js H5流媒体播放器如何验证视频播放是否走硬解

随着技术的不断进步和5G网络的推广&#xff0c;中国流媒体播放器行业市场规模以及未来发展趋势都将持续保持稳定的增长&#xff0c;并将在未来几年迎来新的发展机遇。流媒体播放器将继续作为连接内容创作者和观众的重要桥梁&#xff0c;推动数字媒体产业的创新和发展。 EasyPla…

仿Mybatis代码生成.获取索引信息

获取索引信息 1.核心思路 通过以下sql语句&#xff0c;例如对于user表 show index from user 执行结果如下: 2.实现 连接数据库后执行sql语句&#xff0c;我们重点关注下图标注的三个熟悉 代码如下: PreparedStatement ps null;ResultSet fieldResult null;List<Fiel…

【AI大模型】大型语言模型LLM基础概览:技术原理、发展历程与未来展望

目录 &#x1f354; 大语言模型 (LLM) 背景 &#x1f354; 语言模型 (Language Model, LM) 2.1 基于规则和统计的语言模型&#xff08;N-gram&#xff09; 2.2 神经网络语言模型 2.3 基于Transformer的预训练语言模型 2.4 大语言模型 &#x1f354; 语言模型的评估指标 …

详解八大排序(一)------(插入排序,选择排序,冒泡排序,希尔排序)

文章目录 前言1.插入排序&#xff08;InsertSort&#xff09;1.1 核心思路1.2 实现代码 2.选择排序&#xff08;SelectSort&#xff09;2.1 核心思路2.2 实现代码 3.冒泡排序&#xff08;BubbleSort&#xff09;3.1 核心思路3.2 实现代码 4.希尔排序&#xff08;ShellSort&…

如何在 Ubuntu 上使用 Docker 部署 LibreOffice Online

简介 LibreOffice Online&#xff08;也称为Collabora Online&#xff09;是一个开源的在线办公套件&#xff0c;它提供了与LibreOffice桌面版相似的功能&#xff0c;但完全在云端运行。这意味着用户可以通过浏览器访问和编辑文档&#xff0c;而无需在本地计算机上安装任何软件…

【人工智能】PyTorch、TensorFlow 和 Keras 全面解析与对比:深度学习框架的终极指南

文章目录 PyTorch 全面解析2.1 PyTorch 的发展历程2.2 PyTorch 的核心特点2.3 PyTorch 的应用场景 TensorFlow 全面解析3.1 TensorFlow 的发展历程3.2 TensorFlow 的核心特点3.3 TensorFlow 的应用场景 Keras 全面解析4.1 Keras 的发展历程4.2 Keras 的核心特点4.3 Keras 的应用…

macOS 无法安装第三方app,启用任何来源的方法

升级新版本 MacOS 后&#xff0c;安装下载的软件时&#xff0c;不能在 ”安全性与隐私” 中找不到 ”任何来源” 选项。 1. 允许展示任何来源 点击 启动器 (Launchpad) – 其他 (Other) – 终端 (Terminal)&#xff1a; 打开终端后&#xff0c;输入以下代码回车&#xff1a; …

Flutter:RotationTransition旋转动画

配置vsync&#xff0c;需要实现一下with SingleTickerProviderStateMixinclass _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin{// 定义 AnimationController late AnimationController _controller;overridevoid initState() {super…

同步的意义以及机制

一、同步的意义 同步&#xff08;Synchronization&#xff09;的意义在于确保在多线程环境中&#xff0c;多个线程对共享资源的访问是安全的&#xff0c;避免竞争条件&#xff08;race conditions&#xff09;和数据不一致的情况。 具体来说&#xff0c;同步的核心目标是&…

第二十四章 Spring之源码阅读——AOP篇

Spring源码阅读目录 第一部分——IOC篇 第一章 Spring之最熟悉的陌生人——IOC 第二章 Spring之假如让你来写IOC容器——加载资源篇 第三章 Spring之假如让你来写IOC容器——解析配置文件篇 第四章 Spring之假如让你来写IOC容器——XML配置文件篇 第五章 Spring之假如让你来写…

C++语言之STL

STL STL是标准模板库,是惠普实验室开发的一系列软件的统称 STL的6大组件 容器 算法 迭代器 仿函数 适配器 空间适配器 容器 作用:容纳存储的数据 分类: 序列式容器: 强调值的顺序,每个元素均有固定的位置,除非用删除或插入的操作改变这个位置,如vector,deque/queue,list; 关联式…

嵌入式实验报告:家用计时器

实验目的和要求 1、实验目的 掌握STM32串口通信原理。学习编程实现STM32的UART通信掌握STM32中断程序设计流程。熟悉STM32固件库的基本使用。熟悉STM32定时器中断设计流程。2、实验要求 设计一个家用计时器,其功能如下: 利用串口设置计时时间,格式:XX:XX:X 例如01:59:…