当前位置: 首页 > news >正文

操作系统课程实验1-进程调度模拟实验

操作系统课程实验1-进程调度模拟实验

一、实验介绍

1.1 实验目的

本实验模拟在单处理机环境下的处理机调度,帮助理解进程调度的概念,深入了解进程控制块的功能,以及进程的创建、撤销和进程各个状态间的转换过程。

1.2 实验内容
  1. 进程调度算法:采用最高优先数优先的调度算法、先来先服务算法、SJF和多级反馈调度算法。
  2. 每个进程有一个进程控制块(PCB)表示。进程控制块可以包含如下信息:进程名、优先数、到达时间、需要运行时间、已用CPU时间、进程状态等等。进程的优先数及需要的运行时间可以事先人为输入(也可以由随机数产生)。进程的到达时间为进程输入的时间。 进程的运行时间以时间片为单位进行计算。
1.3 实验要求
  1. 每进行一次调度程序都显示输出一次运行进程、就绪队列、以及各个进程的PCB,以便进行检查。
  2. 对同一组进程的各种调度算法分别计算平均周转时间和平均带权周转时间。
1.4 参考测试数据

系统有5个进程,其就绪时刻、服务时间和优先级(优先级数值越大优先级越高)如下图所示:
在这里插入图片描述

多级反馈队列调度算法:设3个就绪队列,时间片分别为1、2、3。

二、实现代码

#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>using namespace std;typedef struct ProcessControlBlock { // 定义进程控制块结构体int name;                   // 进程名称unsigned int Arrive_Time;   // 到达时间unsigned int Wait_Time;     // 等待时间unsigned int Start_Time;    // 开始时间unsigned int Serve_Time;    // 服务时间unsigned int Finish_Time;   // 完成时间int Priority;               // 优先级unsigned int cycle_time;    // 周转时间double Weighted_cycle_time; // 带权周转时间unsigned int Original_Serve_Time;bool FinishFlag;            // 完成标志
} PCB;                          // 进程控制块的别名typedef struct Multilevel_Feedback_Queue { // 定义多级反馈队列int L1_Length, L1[5];       // 第一级别反馈队列int L2_Length, L2[5];       // 第二级别反馈队列int L3_Length, L3[5];       // 第三级别反馈队列unsigned int Time_Slice[3]; // 三级反馈队列分配的时间片
} MFQ;void PCB_Info_Input(PCB Process_HPF[5], PCB Process_FCFS[5], PCB Process_SJF[5], PCB Process_MFQ[5]); 					 	// 函数声明:输入进程控制块信息void Highest_Prioriy_First(PCB  Process[5]); 	// 函数声明:最高优先级优先算法
void First_Come_First_Serve(PCB Process[5]); 	// 函数声明:先来先服务算法
void Shortest_Job_First(PCB Process[5]);	 	// 函数声明:短作业优先算法
void Multilevel_Feedback_Queue_Algorithm(PCB Process[5]);	// 函数声明:多级反馈队列算法
void Multilevel_Feedback_Queue_Algorithm_Input(MFQ * mfq);	// 函数声明:多级反馈队列的输入bool SortBy_Priority(PCB* a, PCB* b);		 	// 函数声明:按优先级排序
bool SortBy_ServeTime(PCB* a, PCB* b);		 	// 函数声明:按服务时间排序
bool SortBy_ArriveTime(PCB a, PCB b);		 	// 函数声明:按到达时间排序int main(void) {PCB Process_HPF[5]; 								// 定义5个进程控制块数组PCB Process_FCFS[5]; 								// 定义5个进程控制块数组PCB Process_SJF[5]; 								// 定义5个进程控制块数组PCB Process_MFQ[5]; 								// 定义5个进程控制块数组PCB_Info_Input(Process_HPF, Process_FCFS, Process_SJF, Process_MFQ); 								// 调用输入进程控制块信息函数Highest_Prioriy_First(Process_HPF); 				// 调用优先级最高优先算法函数First_Come_First_Serve(Process_FCFS); 				// 调用先来先服务算法函数Shortest_Job_First(Process_SJF);	 				// 调用短作业优先算法函数Multilevel_Feedback_Queue_Algorithm(Process_MFQ); 	// 调用多级反馈队列调度算法return 0;
}//	3比较函数,用于sort函数的参数
bool SortBy_ArriveTime(PCB a, PCB b) {return a.Arrive_Time < b.Arrive_Time;
}
bool SortBy_Priority(PCB* a, PCB* b) {return a->Priority < b->Priority;
}
bool SortBy_ServeTime(PCB* a, PCB* b) {return a->Serve_Time < b->Serve_Time;
}void PCB_Info_Input(PCB Process_HPF[5], PCB Process_FCFS[5], PCB Process_SJF[5], PCB Process_MFQ[5]) {cout << "\nPlease input the Process Control Block information\n" << endl;for (int i = 0; i < 5; i++) {printf("PCB%d:", i);scanf("%u%u%d", &Process_HPF[i].Arrive_Time, &Process_HPF[i].Serve_Time, &Process_HPF[i].Priority);// 完成输入的深拷贝Process_FCFS[i].Arrive_Time = Process_SJF[i].Arrive_Time = Process_MFQ[i].Arrive_Time = Process_HPF[i].Arrive_Time;Process_FCFS[i].Serve_Time = Process_SJF[i].Serve_Time = Process_MFQ[i].Serve_Time = Process_HPF[i].Serve_Time;Process_FCFS[i].Priority = Process_SJF[i].Priority = Process_MFQ[i].Priority = Process_HPF[i].Priority;Process_HPF[i].name = Process_FCFS[i].name = Process_SJF[i].name = Process_MFQ[i].name = i + 1; 							// 设置进程名称Process_HPF[i].FinishFlag = Process_FCFS[i].FinishFlag = Process_SJF[i].FinishFlag = Process_MFQ[i].FinishFlag = false; 	// 初始化完成标志为false}
}// 优先级最高优先调度算法函数
void Highest_Prioriy_First(PCB Process[5]) {cout << "\n优先级最高优先调度算法:" << endl;PCB* Available_Processes[5]; 	// 定义指向进程控制块的指针数组int FinishCout = 0; 			// 完成进程计数器初始化为0unsigned Time = 0; 				// 时间初始化为0cout << endl;sort(Process, Process + 5, SortBy_ArriveTime);  // 按到达时间对进程数组进行排序while (FinishCout < 5) { 						// 当完成进程数量小于5时循环执行调度算法,因为进程还有进程未得到处理机时间int j = 0; 									// 已到达且未完成进程计数器初始化为0for (int i = 0; i < 5; i++) { 				// 循环遍历所有进程if (Process[i].Arrive_Time <= Time and Process[i].FinishFlag == false) { // 如果进程已到达且未完成Available_Processes[j++] = Process + i; 							 // 将该进程加入到可用进程数组中}}// 如果j为0,表示当前时间没有到达的进程,此时应该让时间继续推进if (j == 0) {Time += 1; 	// 时间加1continue; 	// 继续下一次循环}// 将当前时间已经到达的所有进程按优先级进行排序sort(Available_Processes, Available_Processes + j, SortBy_Priority);// 选取优先级最大的进程执行任务Available_Processes[0]->Start_Time = Time; 	// 设置进程开始时间Available_Processes[0]->Wait_Time = Available_Processes[0]->Arrive_Time; // 设置进程等待时间Time += Available_Processes[0]->Serve_Time; // 更新时间Available_Processes[0]->Finish_Time = Time; // 设置进程完成时间Available_Processes[0]->cycle_time = Available_Processes[0]->Finish_Time - Available_Processes[0]->Arrive_Time; 	// 计算进程周转时间Available_Processes[0]->Weighted_cycle_time = Available_Processes[0]->cycle_time * 1.0 / Available_Processes[0]->Serve_Time;Available_Processes[0]->FinishFlag = true; 	// 设置进程完成标志为truecout << "PCB:" << Available_Processes[0]->name << "\tArriveTime:" << Available_Processes[0]->Arrive_Time<< "\tPriority:" << Available_Processes[0]->Priority<< "\tWaitTime:" << Available_Processes[0]->Wait_Time<< "\tStartTime:" << Available_Processes[0]->Start_Time<< "\tServeTime:" << Available_Processes[0]->Serve_Time<< "\tFinishTime:" << Available_Processes[0]->Finish_Time<< "\tCircleTime:" << Available_Processes[0]->cycle_time<< endl; // 输出进程完成信息FinishCout += 1; 							// 完成进程计数器加1}double avg = 0, weighted_avg = 0;for (int i = 0; i < 5; i++) {      // 遍历进程数组avg += Process[i].cycle_time;     // 计算总周转时间weighted_avg += Process[i].Weighted_cycle_time; // 计算总带权周转时间}avg /= 5; // 计算平均周转时间weighted_avg /= 5; // 计算带权平均周转时间cout << "\n平均周转时间:" << avg << endl;          // 输出平均周转时间cout << "带权平均周转时间:" << weighted_avg << endl; // 输出带权平均周转时间
}// 先来先服务调度算法(FCFS)
void First_Come_First_Serve(PCB  Process[5]) {cout << "\n先来先服务调度算法:" << endl;int FinishCout = 0; 	// 完成进程计数器初始化为0unsigned Time = 0; 		// 时间初始化为0cout << endl;sort(Process, Process + 5, SortBy_ArriveTime); // 按到达时间对进程数组进行排序while (FinishCout < 5) { // 当完成进程数量小于5时循环执行调度算法,因为进程还有进程未得到处理机时间int j = -1; 		 // 已到达且未完成进程计数器初始化为0for (int i = 0; i < 5; i++) { // 循环遍历所有进程if (Process[i].Arrive_Time <= Time and Process[i].FinishFlag == false) {j = i;break;}}// 如果j为-1,表示当前时间没有到达的进程,此时应该让时间继续推进if (j == -1) {Time += 1; 	// 时间加1continue; 	// 继续下一次循环}// 选取当前满足条件且到达时间最早的进程进行执行Process[j].Start_Time = Time; 	// 设置进程开始时间Process[j].Wait_Time = Process[j].Start_Time - Process[j].Arrive_Time; // 设置进程等待时间Time += Process[j].Serve_Time; 	// 更新时间Process[j].Finish_Time = Time; 	// 设置进程完成时间Process[j].cycle_time = Process[j].Finish_Time - Process[j].Arrive_Time; 				// 计算进程周转时间Process[j].Weighted_cycle_time = Process[j].cycle_time * 1.0 / Process[j].Serve_Time;Process[j].FinishFlag = true; 	// 设置进程完成标志为truecout << "PCB:" << Process[j].name << "\tArriveTime:" << Process[j].Arrive_Time<< "\tWaitTime:" << Process[j].Wait_Time<< "\tStartTime:" << Process[j].Start_Time<< "\tServeTime:" << Process[j].Serve_Time<< "\tFinishTime:" << Process[j].Finish_Time<< "\tCircleTime:" << Process[j].cycle_time<< endl; // 输出进程完成信息FinishCout += 1; // 完成进程计数器加1}double avg = 0, weighted_avg = 0;for (int i = 0; i < 5; i++) {      // 遍历进程数组avg += Process[i].cycle_time;     // 计算总周转时间weighted_avg += Process[i].Weighted_cycle_time; // 计算总带权周转时间}avg /= 5; // 计算平均周转时间weighted_avg /= 5; // 计算带权平均周转时间cout << "\n平均周转时间:" << avg << endl;          // 输出平均周转时间cout << "带权平均周转时间:" << weighted_avg << endl; // 输出带权平均周转时间
}// 短作业优先算法 (SJF)
void Shortest_Job_First(PCB Process[5]) {cout << "\n短作业优先算法:" << endl;PCB* Available_Processes[5]; 	// 定义指向进程控制块的指针数组int FinishCout = 0; 			// 完成进程计数器初始化为0unsigned Time = 0; 				// 时间初始化为0cout << endl;sort(Process, Process + 5, SortBy_ArriveTime); // 按到达时间对进程数组进行排序while (FinishCout < 5) { 	// 当完成进程数量小于5时循环执行调度算法,因为进程还有进程未得到处理机时间int j = 0; 				// 已到达且未完成进程计数器初始化为0for (int i = 0; i < 5; i++) { // 循环遍历所有进程if (Process[i].Arrive_Time <= Time and Process[i].FinishFlag == false) { 	// 如果进程已到达且未完成Available_Processes[j++] = Process + i; 								// 将该进程加入到可用进程数组中}}// 如果j为0,表示当前时间没有到达的进程,此时应该让时间继续推进if (j == 0) {Time += 1; 	// 时间加1continue; 	// 继续下一次循环}// 将当前时间已经到达的所有进程按服务时间进行排序sort(Available_Processes, Available_Processes + j, SortBy_ServeTime);// 选取当前满足条件且服务时间最短的进程执行任务Available_Processes[0]->Start_Time = Time; 	// 设置进程开始时间Available_Processes[0]->Wait_Time = Available_Processes[0]->Arrive_Time; // 设置进程等待时间Time += Available_Processes[0]->Serve_Time; // 更新时间Available_Processes[0]->Finish_Time = Time; // 设置进程完成时间Available_Processes[0]->cycle_time = Available_Processes[0]->Finish_Time - Available_Processes[0]->Arrive_Time; 	// 计算进程周转时间Available_Processes[0]->Weighted_cycle_time = Available_Processes[0]->cycle_time * 1.0 / Available_Processes[0]->Serve_Time;Available_Processes[0]->FinishFlag = true; 	// 设置进程完成标志为truecout << "PCB:" << Available_Processes[0]->name << "\tArriveTime:" << Available_Processes[0]->Arrive_Time<< "\tWaitTime:" << Available_Processes[0]->Wait_Time<< "\tStartTime:" << Available_Processes[0]->Start_Time<< "\tServeTime:" << Available_Processes[0]->Serve_Time<< "\tFinishTime:" << Available_Processes[0]->Finish_Time<< "\tCircleTime:" << Available_Processes[0]->cycle_time<< endl; // 输出进程完成信息FinishCout += 1; 							// 完成进程计数器加1}double avg = 0, weighted_avg = 0;for (int i = 0; i < 5; i++) {      // 遍历进程数组avg += Process[i].cycle_time;     // 计算总周转时间weighted_avg += Process[i].Weighted_cycle_time; // 计算总带权周转时间}avg /= 5; // 计算平均周转时间weighted_avg /= 5; // 计算带权平均周转时间cout << "\n平均周转时间:" << avg << endl;          // 输出平均周转时间cout << "带权平均周转时间:" << weighted_avg << endl; // 输出带权平均周转时间}void Multilevel_Feedback_Queue_Algorithm(PCB Process[5]) {cout << "\n多级反馈队列调度算法:" << endl;MFQ MFQSet;Multilevel_Feedback_Queue_Algorithm_Input(&MFQSet); // 调用输入多级反馈队列的函数queue<PCB> L1, L2, L3; // 定义三个队列sort(Process, Process + 5, SortBy_ArriveTime); // 按到达时间对进程数组进行排序unsigned int Time = 0; // 时间初始化为0double avg = 0, weighted_avg = 0; // 初始化平均周转时间和带权平均周转时间for (int i = 0; i < 5; i++) { // 将进程按照到达时间加入到第一级别队列Process[i].Original_Serve_Time = Process[i].Serve_Time;L1.push(Process[i]);}while (!L1.empty() || !L2.empty() || !L3.empty()) { // 当三个队列有不为空的时循环cout << "Time:" << Time << " \t\t"; // 输出当前时间if (!L1.empty()) { // 如果第一级别队列不为空PCB temp = L1.front(); // 获取队首进程L1.pop();              // 弹出队首进程cout << "P" << temp.name << " is processing:"; // 输出当前处理的进程名称Time += min(temp.Serve_Time, MFQSet.Time_Slice[0]); // 时间增加当前进程的服务时间或者时间片长度中较小的那个temp.Serve_Time = max(0, (int)(temp.Serve_Time - MFQSet.Time_Slice[0])); // 更新当前进程的服务时间if (temp.Serve_Time == 0) { // 如果当前进程的服务时间为0temp.Finish_Time = Time; // 设置当前进程的完成时间temp.cycle_time = temp.Finish_Time - temp.Arrive_Time;   // 计算当前进程的周转时间temp.Weighted_cycle_time = (double)temp.cycle_time / temp.Original_Serve_Time; // 计算当前进程的带权周转时间avg += temp.cycle_time;     // 计算总周转时间weighted_avg += temp.Weighted_cycle_time; // 计算总带权周转时间cout << "Finish Time:" << Time << endl; // 输出当前进程的完成时间} else {cout << 'P' << temp.name << "转移到队列2的末尾\n";L2.push(temp); // 否则将当前进程加入到第二级别队列}} else if (!L2.empty()) { // 如果第一级别队列为空但第二级别队列不为空PCB temp = L2.front(); // 获取队首进程L2.pop();              // 弹出队首进程cout << "P" << temp.name << " is processing:"; // 输出当前处理的进程名称Time += min(temp.Serve_Time, MFQSet.Time_Slice[1]); // 时间增加当前进程的服务时间或者时间片长度中较小的那个temp.Serve_Time = max(0, (int)(temp.Serve_Time - MFQSet.Time_Slice[1])); // 更新当前进程的服务时间if (temp.Serve_Time == 0) { // 如果当前进程的服务时间为0temp.Finish_Time = Time; // 设置当前进程的完成时间temp.cycle_time = temp.Finish_Time - temp.Arrive_Time;   // 计算当前进程的周转时间temp.Weighted_cycle_time = (double)temp.cycle_time / temp.Original_Serve_Time; // 计算当前进程的带权周转时间avg += temp.cycle_time;     // 计算总周转时间weighted_avg += temp.Weighted_cycle_time; // 计算总带权周转时间cout << "Finish Time:" << Time << endl; // 输出当前进程的完成时间} else {cout << 'P' << temp.name << "转移到队列3的末尾\n";L3.push(temp); // 否则将当前进程加入到第三级别队列}} else { // 如果第一级别和第二级别队列均为空while (!L3.empty()) {PCB temp = L3.front(); // 获取队首进程L3.pop();              // 弹出队首进程cout << "P" << temp.name << " is processing:"; // 输出当前处理的进程名称Time += min(temp.Serve_Time, MFQSet.Time_Slice[2]); // 时间增加当前进程的服务时间或者时间片长度中较小的那个temp.Serve_Time = max(0, (int)(temp.Serve_Time - MFQSet.Time_Slice[2])); // 更新当前进程的服务时间if (temp.Serve_Time == 0) { // 如果当前进程的服务时间为0temp.Finish_Time = Time; // 设置当前进程的完成时间temp.cycle_time = temp.Finish_Time - temp.Arrive_Time;   // 计算当前进程的周转时间temp.Weighted_cycle_time = (double)temp.cycle_time / temp.Original_Serve_Time; // 计算当前进程的带权周转时间avg += temp.cycle_time;     // 计算总周转时间weighted_avg += temp.Weighted_cycle_time; // 计算总带权周转时间cout << "Finish Time:" << Time << endl; // 输出当前进程的完成时间} else {cout << 'P' << temp.name << "继续执行\n";L3.push(temp); // 将当前进程加入到第三级别队列末尾}}}}avg /= 5; // 计算平均周转时间weighted_avg /= 5; // 计算带权平均周转时间cout << "\n平均周转时间:" << avg << endl;          // 输出平均周转时间cout << "带权平均周转时间:" << weighted_avg << endl; // 输出带权平均周转
}// 输入多级反馈队列的函数
void Multilevel_Feedback_Queue_Algorithm_Input(MFQ *mfq) {cout << "Please input the Time Slice(Three Numbers) for Multilevel Feedback Queue" << endl;cin >> mfq->Time_Slice[0] >> mfq->Time_Slice[1] >> mfq->Time_Slice[2];
}

三、心灵的救赎

  1. “爱”就是科学与逻辑永远无法解释的程序
    在这里插入图片描述

相关文章:

操作系统课程实验1-进程调度模拟实验

操作系统课程实验1-进程调度模拟实验 一、实验介绍 1.1 实验目的 本实验模拟在单处理机环境下的处理机调度&#xff0c;帮助理解进程调度的概念&#xff0c;深入了解进程控制块的功能&#xff0c;以及进程的创建、撤销和进程各个状态间的转换过程。 1.2 实验内容 进程调度算…...

JVM CMS 在Full GC时针对跨代引用的优化

个人博客 JVM CMS 在Full GC时针对跨代引用的优化 | iwts’s blog 跨代引用问题 Full GC慢的一个很重要的问题&#xff1a;跨代引用。 简单描述就是&#xff1a; 现代JVM一般是根据对象存活的特性进行了分代&#xff0c;提高了垃圾收集的效率。但是像在回收新生代的时候&a…...

【Makefile】Makefile 编译 Keil 工程(Linux 环境)

本文使用的开发板为 stm32f103C8T6&#xff0c;使用的驱动库为stm32标准库。 目录 一、软件下载 1、stm32 标准库 2、arm-none-eabi 工具链 3、烧录器 二、Keil 工程改造 1、Keil 工程 2、基本 Makefile 工程 3、添加启动文件 4、添加链接脚本 5、去掉 core_cm3.c 三…...

Django的视图层——1HttpResponse对象详解

在django.http模块中定义了HttpResponse对象的APIHttpRequest对象由Django自动创建&#xff0c;HttpResponse对象由程序员创建在每一个视图函数中必须返回一个HttpResponse对象,当然也可以是HttpResponse子对象 1.不用模板,直接返回数据 from django.http import HttpRespons…...

企业活动想找媒体报道宣传怎样联系媒体?

在那遥远的公关江湖里,有一个传说,说的是一位勇士,手持鼠标和键盘,踏上了寻找媒体圣杯的征途。这位勇士,就是我们亲爱的市场部门小李,他的任务是为公司即将举行的一场盛大的企业活动找到媒体的聚光灯。 小李的故事,开始于一张空白的Excel表格,上面列着各大媒体的名称,旁边是一片…...

基于ChatGPT+RPA的融资融券业务担保资产风险评价

原载《会计之友》2024年第2期 作者简介 李闻一 男&#xff0c;湖北洪湖人&#xff0c;华中师范大学经济与工商管理学院教授、博士生导师&#xff0c;会计学科带头人&#xff0c;研究方向&#xff1a;财务共享、公司金融、风险管理 黄怡凡 女&#xff0c;湖北公安人&#xf…...

2. CSS选择器与伪类

2.1 基本选择器回顾 在开始介绍CSS3选择器之前&#xff0c;我们先回顾一下CSS的基本选择器。这些选择器是所有CSS开发的基础。 2.1.1 元素选择器 元素选择器用于选中指定类型的HTML元素。 /* 选中所有的<p>元素 */ p {color: blue; }2.1.2 类选择器 类选择器用于选中…...

tcpdump源码分析

进入tcpdump.c&#xff08;函数入口&#xff09;之前&#xff0c;先看一些头文件netdissect.h里定义了一个数据结构struct netdissect_options来描述tcdpump支持的所有参数动作&#xff0c;每一个参数有对应的flag, 在tcpdump 的main 里面&#xff0c; 会根据用户的传入的参数来…...

搭建Harbor镜像仓库

前言 1、系统版本&#xff1a;CentOS9 2、harbor版本&#xff1a;v2.9.4 3、提前安装好docker和docker-compose&#xff0c;参考地址。我这里安装的版本是docker&#xff1a;26.1.3 docker-compose&#xff1a;v2.27.1 安装步骤 下载安装包 1、下载地址&#xff1a;ha…...

【C/C++】Makefile文件的介绍与基本用法

创作不易&#xff0c;本篇文章如果帮助到了你&#xff0c;还请点赞 关注支持一下♡>&#x16966;<)!! 主页专栏有更多知识&#xff0c;如有疑问欢迎大家指正讨论&#xff0c;共同进步&#xff01; &#x1f525;c系列专栏&#xff1a;C/C零基础到精通 &#x1f525; 给大…...

PHP生成二维码+二维码包含logo图片展示

composer require chillerlan/php-qrcode 用到的扩展自己安装&#xff08;注&#xff1a;只生成二维码只要开gd扩展就行&#xff09; 仅生成二维码看这个&#xff1a; use chillerlan\QRCode\QRCode;public function QRCode(){$qrcode new QRCode();$url "http://ww…...

vue项目打包教程

如果是用 vue-cli 创建的项目&#xff0c;则项目目录中没有 config 文件夹&#xff0c;所以我们需要自建一个配置文件&#xff1b;在vue项目目录下创建文件 vue.config.js&#xff0c;需注意文件名称必须是 vue.config.js&#xff0c;然后在文件中插入以下代码&#xff1a; 文件…...

制作电子画册速成攻略,快来试试

​当今社会&#xff0c;数字媒体日益普及&#xff0c;电子画册作为一种崭新的展示方式&#xff0c;受到了越来越多人的青睐。它不仅形式新颖&#xff0c;互动性强&#xff0c;而且制作起来也并不复杂。想知道如何快速掌握制作电子画册的技巧吗&#xff1f;我来教你吧。 接下来&…...

【java程序设计期末复习】chapter7 内部类和异常类

内部类和异常类 内部类 ava支持在一个类中声明另一个类&#xff0c;这样的类称作内部类&#xff0c;而包含内部类的类成为内部类的外嵌类。 注意 &#xff08;1&#xff09;内部类的类体中不可以声明类变量和类方法。 &#xff08;2&#xff09;外嵌类的类体中可以用内部类…...

Windows下安装配置深度学习环境

Windows下安装配置深度学习环境 1. 准备工作 1.1 环境准备 操作系统&#xff1a;win10 22H2 GPU&#xff1a;Nvidia GeForce RTX 3060 12G 1.2 安装Nvidia驱动、cuda、cuDNN 下载驱动需要注册并登录英伟达账号。我这里将下面用到的安装包放到了百度网盘&#xff0c;可以关注微信…...

如何使用ssh将vscode 连接到服务器上,手把手指导

一、背景 我们在开发时&#xff0c;经常是window上安装一个vscode编辑器&#xff0c;去连接一个虚拟机上的linux&#xff0c;这里常用的是SSH协议&#xff0c;了解其中的操作非常必要。 二、SSH协议 SSH&#xff08;Secure Shell&#xff09;是一种安全协议&#xff0c;用于…...

Tomcat调优参数

JVM优化 Tomcat是一个Web容器&#xff0c;所有的jar其实都共享Tomcat中的JVM参数&#xff0c;所以Tomcat的JVM参数优化至关重要。 Tomcat的JVM参数是在启动脚本中设置的&#xff0c;如想要设置最大堆内存和最小堆内存时&#xff1a; 在windows的启动脚本catalina.bat中的set &q…...

云计算和大数据处理

文章目录 1.云计算基础知识1.1 基本概念1.2 云计算分类 2.大数据处理基础知识2.1 基础知识2.3 大数据处理技术 1.云计算基础知识 1.1 基本概念 云计算是一种提供资源的网络&#xff0c;使用者可以随时获取“云”上的资源&#xff0c;按需求量使用&#xff0c;并且可以看成是无…...

VAE-变分自编码器(Variational Autoencoder,VAE)

变分自编码器&#xff08;Variational Autoencoder&#xff0c;VAE&#xff09;是一种生成模型&#xff0c;结合了概率图模型与神经网络技术&#xff0c;广泛应用于数据生成、表示学习和数据压缩等领域。以下是对VAE的详细解释和理解&#xff1a; 基本概念 1. 自编码器&#…...

Android Room 使用模版

文章目录 一、配置依赖 plugins {id kotlin-kapt }android {compileOptions {sourceCompatibility JavaVersion.VERSION_17targetCompatibility JavaVersion.VERSION_17}kotlinOptions {jvmTarget 17} }dependencies {implementation("androidx.room:room-runtime:2.4.2&…...

synchronized 学习

学习源&#xff1a; https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖&#xff0c;也要考虑性能问题&#xff08;场景&#xff09; 2.常见面试问题&#xff1a; sync出…...

Spark 之 入门讲解详细版(1)

1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室&#xff08;Algorithms, Machines, and People Lab&#xff09;开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目&#xff0c;8个月后成为Apache顶级项目&#xff0c;速度之快足见过人之处&…...

CMake基础:构建流程详解

目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

蓝桥杯 2024 15届国赛 A组 儿童节快乐

P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡&#xff0c;轻快的音乐在耳边持续回荡&#xff0c;小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下&#xff0c;六一来了。 今天是六一儿童节&#xff0c;小蓝老师为了让大家在节…...

【C语言练习】080. 使用C语言实现简单的数据库操作

080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...

MySQL用户和授权

开放MySQL白名单 可以通过iptables-save命令确认对应客户端ip是否可以访问MySQL服务&#xff1a; test: # iptables-save | grep 3306 -A mp_srv_whitelist -s 172.16.14.102/32 -p tcp -m tcp --dport 3306 -j ACCEPT -A mp_srv_whitelist -s 172.16.4.16/32 -p tcp -m tcp -…...

rnn判断string中第一次出现a的下标

# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...

Python 包管理器 uv 介绍

Python 包管理器 uv 全面介绍 uv 是由 Astral&#xff08;热门工具 Ruff 的开发者&#xff09;推出的下一代高性能 Python 包管理器和构建工具&#xff0c;用 Rust 编写。它旨在解决传统工具&#xff08;如 pip、virtualenv、pip-tools&#xff09;的性能瓶颈&#xff0c;同时…...

C++.OpenGL (20/64)混合(Blending)

混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...

comfyui 工作流中 图生视频 如何增加视频的长度到5秒

comfyUI 工作流怎么可以生成更长的视频。除了硬件显存要求之外还有别的方法吗&#xff1f; 在ComfyUI中实现图生视频并延长到5秒&#xff0c;需要结合多个扩展和技巧。以下是完整解决方案&#xff1a; 核心工作流配置&#xff08;24fps下5秒120帧&#xff09; #mermaid-svg-yP…...