[操作系统实验(进程调度+存储管理+磁盘调度++银行家算法+文件系统设计)]
操作系统实验(进程调度+存储管理+磁盘调度++银行家算法+文件系统设计) 实验三 进程调度 一、 实验目的 多道程序设计中,经常是若干个进程同时处于就绪状态,必须依照某种策略来决定那个进程优先占有处理机。因而引起进程调度。本实验模拟在单处理机情况下的处理机调度问题,加深对进程调度的理解。
二、 实验要求 1. 设计进程调度算法,进程数不定 2. 包含几种调度算法,并加以实现 3. 输出进程的调度过程——进程的状态、链表等。
三、 参考例 1. 题目——优先权法、轮转法 简化假设 1) 进程为计算型的(无I/O) 2) 进程状态:ready、running、finish 3) 进程需要的CPU时间以时间片为单位确定 2. 算法描述 1) 优先权法——动态优先权 当前运行进程用完时间片后,其优先权减去一个常数。
2) 轮转法 开始 键盘输入进程数n,和调度方法的选择 优先权法? 轮转法 产生n个进程,对每个进程产生一个PCB,并用随机数产生进程的优先权及进程所需的CPU时间 按优先权大小,把n个进程拉成一个就绪队列 初始化其他数据结构区 链首进程投入运行 时间片到,进程所需的CPU时间减1,优先权减3,输出个进程的运行情况 所需的CPU时间=0? 撤销进程 就绪队列为空? 结束 将进程插入就绪队列 N Y N Y Y B N 四、 实验流程图 产生n个进程,对每个进程用随机数产生进程的轮转时间片数及进程所需的时间片数,已占用CPU的时间片数置为0 按进程产生的先后次序拉成就绪队列链 链首进程投入运行 时间片到,进程所需时间片数减1,已占用CPU时间片数加1 输出各进程的运行情况 进程所需时间片数=0? 撤销该进程 就绪队列为空吗? 占用CPU的时间片数=轮转时间片数? 占用CPU的时间片数置为0 把该进程插入就绪队列尾 B N Y N Y Y 结束 N 注意:
1. 产生的各种随机数的取值范围加以限制,如所需的CPU时间限制在1~20之间。
2. 进程数n不要太大通常取4~8个 3. 使用动态数据结构 4. 独立编程 5. 至少三种调度算法 6. 若有可能请在图形方式下,将PCB的调度用图形成动画显示。
五.实验过程:
(1)输入:进程流文件(1.txt),其中存储的是一系列要执行的进程, 每个作业包括四个数据项:
进程名 进程状态(1就绪 2等待 3运行) 所需时间 优先数(0级最高) 进程0 1 50 2 进程1 2 10 4 进程2 1 15 0 进程3 3 28 5 进程4 2 19 1 进程5 3 8 7 输出: 进程执行流等待时间,平均等待时间 本程序包括:FIFO算法,优先数调度算法,时间片轮转调度算法 (2)程序代码 #include<stdio.h> #include<string.h> #include<iostream.h> const int block_time=10; //定义时间片的长度为10秒 const int MAXPCB=100; //定义最大进程数 //定义进程结构体 typedef struct node { char name[20]; int status; int time; int privilege; int finished; int wait_time; }pcb; pcb pcbs[MAXPCB]; int quantity; //初始化函数 void initial() { int i; for(i=0;i<MAXPCB;i++) { strcpy(pcbs[i].name,““); pcbs[i].status=0; pcbs[i].time=0; pcbs[i].privilege=0; pcbs[i].finished=0; pcbs[i].wait_time=0; } quantity=0; } //读数据函数 int readData() { FILE *fp; char fname[20]; int i; cout<<“请输入进程流文件名:“; cin>>fname; if((fp=fopen(fname,“r“))==NULL) { cout<<“错误,文件打不开,请检查文件名“<<endl; } else { while(!feof(fp)) { fscanf(fp,“%s %d %d %d“,pcbs[quantity].name,&pcbs[quantity].status, &pcbs[quantity].time,&pcbs[quantity].privilege); quantity++; } //输出所读入的数据 cout<<“输出所读入的数据“<<endl; cout<<“进程名 进程状态 所需时间 优先数“<<endl; for(i=0;i<quantity;i++) { cout<<“ “<<pcbs[i].name<<“ “<<pcbs[i].status<<“ “<<pcbs[i].time<<“ “<<pcbs[i].privilege<<endl; } return(1); } return(0); } //重置数据,以供另一个算法使用 void init() { int i; for(i=0;i<MAXPCB;i++) { pcbs[i].finished=0; pcbs[i].wait_time=0; } } //先进先出算法 void FIFO() { int i,j; int total; //输出FIFO算法执行流 cout<<endl<<“*****************************************************“<<endl; cout<<“FIFO算法执行流:“<<endl; cout<<“进程名 等待时间“<<endl; for(i=0;i<quantity;i++) { cout<<“ “<<pcbs[i].name<<“ “<<pcbs[i].wait_time<<endl; for(j=i+1;j<quantity;j++) { pcbs[j].wait_time+=pcbs[i].time; } } total=0; for(i=0;i<quantity;i++) { total+=pcbs[i].wait_time; } cout<<“总等待时间:“<<total<<“ 平均等待时间:“<<total/quantity<<endl; } //优先数调度算法 void privilege() { int i,j,p; int passed_time=0; int total; int queue[MAXPCB]; int current_privilege=1000; for(i=0;i<quantity;i++) { current_privilege=1000; for(j=0;j<quantity;j++) { if((pcbs[j].finished==0)&&(pcbs[j].privilege<current_privilege)) { p=j; current_privilege=pcbs[j].privilege; } } queue[i]=p; pcbs[p].finished=1; pcbs[p].wait_time+=passed_time; passed_time+=pcbs[p].time; } //输出优先数调度执行流 cout<<endl<<“***********************************************************“<<endl; cout<<“优先数调度执行流:“<<endl; cout<<“进程名 等待时间“<<endl; for(i=0;i<quantity;i++) { cout<<“ “<<pcbs[queue[i]].name<<“ “<<pcbs[queue[i]].wait_time<<endl; } total=0; for(i=0;i<quantity;i++) { total+=pcbs[i].wait_time; } cout<<“总等待时间:“<<total<<“ 平均等待时间:“<<total/quantity<<endl; } //时间片轮转调度算法 void timer() { int i,j,number,flag=1; int passed_time=0; int max_time=0; int round=0; int queue[1000]; int total=0; while(flag==1) { flag=0; number=0; for(i=0;i<quantity;i++) { if(pcbs[i].finished==0) { number++; j=i; } } if(number==1) { queue[total]=j; total++; pcbs[j].finished=1; } if(number>1) { for(i=0;i<quantity;i++) { if(pcbs[i].finished==0) { flag=1; queue[total]=i; total++; if(pcbs[i].time<=block_time*(round+1)) { pcbs[i].finished=1; } } } } round++; } if(queue[total-1]==queue[total-2]) { total--; } cout<<endl<<“*******************************************************“<<endl; cout<<“时间片轮转调度执行流:“<<endl; for(i=0;i<total;i++) { cout<<pcbs[queue[i]].name<<“ “; cout<<endl; } } //显示 void version() { cout<<“ /********************* 进程调度 ********************/ “; cout<<endl<<endl; } //主函数 void main() { int flag; version(); initial(); flag=readData(); if(flag==1) { FIFO(); init(); privilege(); init(); timer(); } } (3)运行结果:
输入进程流文件名1.txt即可得出以下输出结果:
实验二 银行家算法 一、 实验目的 死锁会引起计算机工作僵死,因此操作系统中必须防止。本实验的目的在于让学生独立的使用高级语言编写和调试一个系统动态分配资源的简单模拟程序,了解死锁产生的条件和原因,并采用银行家算法有效地防止死锁的发生,以加深对课堂上所讲授的知识的理解。
二、 实验要求 设计有n个进程共享m个系统资源的系统,进程可动态的申请和释放资源,系统按各进程的申请动态的分配资源。
系统能显示各个进程申请和释放资源,以及系统动态分配资源的过程,便于用户观察和分析;
三、 数据结构 1. 可利用资源向量Available ,它是一个含有m个元素的数组,其中的每一个元素代表一类可利用的资源的数目,其初始值是系统中所配置的该类全部可用资源数目。其数值随该类资源的分配和回收而动态地改变。如果Available(j)=k,标是系统中现有Rj类资源k个。
2. 最大需求矩阵Max,这是一个n×m的矩阵,它定义了系统中n个进程中的每一个进程对m类资源的最大需求。如果Max(i,j)=k,表示进程i需要Rj类资源的最大数目为k。
3. 分配矩阵Allocation,这是一个n×m的矩阵,它定义了系统中的每类资源当前一分配到每一个进程的资源数。如果Allocation(i,j)=k,表示进程i当前已经分到Rj类资源的数目为k。Allocation i表示进程i的分配向量,有矩阵Allocation的第i行构成。
4. 需求矩阵Need,这是一个n×m的矩阵,用以表示每个进程还需要的各类资源的数目。如果Need(i,j)=k,表示进程i还需要Rj类资源k个,才能完成其任务。Need i表示进程i的需求向量,由矩阵Need的第i行构成。
上述三个矩阵间存在关系:Need(i,j)=Max(i,j)-Allocation(i,j);
四、 银行家算法 Request i 是进程Pi 的请求向量。Request i (j)=k表示进程Pi请求分配Rj类资源k个。当Pi发出资源请求后,系统按下述步骤进行检查:
1. 如果Request i ≤Need,则转向步骤2;
否则,认为出错,因为它所请求的资源数已超过它当前的最大需求量。
2. 如果Request i ≤Available,则转向步骤3;
否则,表示系统中尚无足够的资源满足Pi的申请,Pi必须等待。
3. 系统试探性地把资源分配给进程Pi,并修改下面数据结构中的数值:
Available = Available - Request i Allocation i= Allocation i+ Request i Need i= Need i - Request i 4. 系统执行安全性算法,检查此次资源分配后,系统是否处于安全状态。如果安全才正式将资源分配给进程Pi,以完成本次分配;
否则,将试探分配作废,恢复原来的资源分配状态,让进程Pi等待。
假定系统有5个进程(p0,p1,p2,p3,p4)和三类资源(A,B,C),各种资源的数量分别为10,5,7,在T0时刻的资源分配情况如下图:
Max Allocation Need Available A B C A B C A B C A B C P0 7 5 3 0 1 0 7 4 3 3 3 2 ( 2 3 0 ) P1 3 2 2 2 0 0 1 2 2 (3 0 2 ) (0 2 0 ) P2 9 0 2 3 0 2 6 0 0 P3 2 2 2 2 1 1 0 1 1 P4 4 3 3 0 0 2 4 3 1 五、 安全性算法 1. 设置两个向量。
Work:它表示系统可提供给进程继续运行的各类资源数目,它包含m个元素,开始执行安全性算法时,Work = Available。
Finish:它表示系统是否有足够的资源分配给进程,使之运行完成,开始Finish(I)=false;
当有足够资源分配给进程Pi时,令Finish(i)=true;
2. 从进程集合中找到一个能满足下述条件的进程。
Finish(i)= = false;
Need i ≤work;
如找到则执行步骤3;
否则,执行步骤4;
3. 当进程Pi获得资源后,可顺利执行直到完成,并释放出分配给它的资源,故应执行 Work = work + Allocation i Finish(i)=true;
转向步骤2;
4. 若所有进程的Finish(i)都为true,则表示系统处于安全状态;
否则,系统处于不安全状态。
六、 系统流程图 开 始 输入资源数m, 及各类资源总数,初始化Available向量 输入进程数n,i=1 输入进程i的最大需求向量max。
i≤n max≤资源总数 提示错误重新输入 i加1 任选一个进程作为当前进程 输入该进程的资源请求量Request 调用银行家算法,及安全性算法,完成分配,或并给出提示 该进程的Need向量为0 该进程已运行结束 Need矩阵为0 所有进程运行都结束 结 束 N Y Y N N Y 初始化need 矩阵 N Y 七.银行家算法程序代码 #include<stdio.h> #include<conio.h> #include<iostream> using namespace std; typedef struct Max1 // 资源的最大需求量 { int m_a; int m_b; int m_c; }Max; typedef struct Allocation1 //已分配的资源数 { int a_a; int a_b; int a_c; }Allocation; typedef struct Need1 //还需要的资源数 { int n_a; int n_b; int n_c; }Need; struct Available1 //可利用的资源量 { int av_a; int av_b; int av_c; } q; struct pr //定义一个结构 { char name; Max max; Allocation allocation; Need need; int finishflag; }p[5]; char na[5]; //******************************************** void init() //读入文件“1.txt“ { cout<<“各进程还需要的资源数NEED:“<<endl; FILE *fp; fp=fopen(“1.txt“,“r+“); // 打开文件“1.txt“ for(int i=0;i<5;i++) { fscanf(fp,“%c,%d,%d,%d,%d,%d,%d\n“,&p[i].name,&p[i].max.m_a,&p[i].max.m_b, &p[i].max.m_c,&p[i].allocation.a_a,&p[i].allocation.a_b,&p[i].allocation.a_c); p[i].need.n_a=p[i].max.m_a-p[i].allocation.a_a; p[i].need.n_b=p[i].max.m_b-p[i].allocation.a_b; p[i].need.n_c=p[i].max.m_c-p[i].allocation.a_c; cout<<p[i].name<<“: “<<p[i].need.n_a<<“ “<<p[i].need.n_b<<“ “<<p[i].need.n_c<<endl; } fclose(fp); //关闭文件 } //*********************************************** int fenpei()//分配资源 { cout<<“Available:“; cout<<q.av_a<<“ “<<q.av_b<<“ “<<q.av_c<<endl; int finishcnt=0,k=0,count=0; for(int j=0;j<5;j++) p[j].finishflag=0; while(finishcnt<5) { for(int i=0;i<5;i++) { if(p[i].finishflag==0&&q.av_a>=p[i].need.n_a&&q.av_b>=p[i].need.n_b&&q.av_c>=p[i].need.n_c) { q.av_a+=p[i].allocation.a_a; q.av_b+=p[i].allocation.a_b; q.av_c+=p[i].allocation.a_c; p[i].finishflag=1; finishcnt++; na[k++]=p[i].name; break; } } count++;//禁止循环过多 if(count>5)return 0; } return 1; } //**************************************************** int shq() //申请资源 { int m=0,i=0,j=0,k=0; //m为进程号; i,j,k为申请的三类资源数 cout<<“请输入进程号和请求资源的数目!“<<endl; cout<<“如:进程号 资源A B C“<<endl; cout<<“ 0 2 0 2“<<endl; cin>>m>>i>>j>>k; if(i<=p[m].need.n_a&&j<=p[m].need.n_b &&k<=p[m].need.n_c) { if(i<=q.av_a&&j<=q.av_b&&k<=q.av_c) { p[m].allocation.a_a+=i; p[m].allocation.a_b+=j; p[m].allocation.a_c+=k; p[m].need.n_a=p[m].max.m_a-p[m].allocation.a_a; p[m].need.n_b=p[m].max.m_b-p[m].allocation.a_b; p[m].need.n_c=p[m].max.m_c-p[m].allocation.a_c; cout<<“各进程还需要的资源数NEED:“<<'\n'; for(int w=0;w<5;w++) cout<<p[w].name<<“: “<<p[w].need.n_a<<“ “<<p[w].need.n_b <<“ “<<p[w].need.n_c<<endl; return 1; } else cout<<“Request>Available让进程“<<m<<“等待......“<<endl; } else cout<<“Request>Need,让进程“<<m<<“等待......“<<endl; return 0; } //******************************************** void main() { int flag; char c; cout<<“ /******** 银 行 家 算 法********/ “<<endl; cout<<“确认已经在\“1.txt\“文档中正确输入各进程的有关信息后按回车键“<<endl; getch(); init(); q.av_a=10; //各种资源的数量 q.av_b=5; q.av_c=7; while(flag) { for(int i=0;i<5;i++) { q.av_a-= p[i].allocation.a_a; q.av_b-= p[i].allocation.a_b; q.av_c-= p[i].allocation.a_c; } if(fenpei()) { cout<<“这样配置资源是安全的!“<<endl; cout<<“其安全序列是:
“; for(int k=0;k<5;k++) cout<<“-->“<<na[k]; cout<<endl; cout<<“有进程发出Request请求向量吗?(Enter y or Y)“<<endl; cout<<endl; c=getch(); if(c=='y'||c=='Y') { if(shq())continue; else break; } else flag=0; } else {flag=0; cout<<“不安全!!!“<<endl;} } } 八.运行结果 实验三 存储管理 一. 实验目的 存储管理的主要功能之一是合理地分配空间。请求页式管理是一种常用的虚拟存储管理技术。
本实验的目的是通过请求页式管理中页面置换算法模拟设计,了解虚拟存储技术的特点,掌握请求页式存储管理的页面置换算法。
二. 实验内容 (1) 通过计算不同算法的命中率比较算法的优劣。同时也考虑了用户内存容量对命中率的影响。
页面失效次数为每次访问相应指令时,该指令所对应的页不在内存中的次数。
在本实验中,假定页面大小为1k,用户虚存容量为32k,用户内存容量为4页到32页。
(2) produce_addstream通过随机数产生一个指令序列,共320条指令。
A、 指令的地址按下述原则生成:
1) 50%的指令是顺序执行的 2) 25%的指令是均匀分布在前地址部分 3) 25%的指令是均匀分布在后地址部分 B、 具体的实施方法是:
1) 在[0,319]的指令地址之间随机选取一起点m;
2) 顺序执行一条指令,即执行地址为m+1的指令;
3) 在前地址[0,m+1]中随机选取一条指令并执行,该指令的地址为m’;
4) 顺序执行一条指令,地址为m’+1的指令 5) 在后地址[m’+2,319]中随机选取一条指令并执行;
6) 重复上述步骤1)~5),直到执行320次指令 C、 将指令序列变换称为页地址流 在用户虚存中,按每k存放10条指令排列虚存地址,即320条指令在虚存中的存放方式为:
第0条~第9条指令为第0页(对应虚存地址为[0,9]);
第10条~第19条指令为第1页(对应虚存地址为[10,19]);
。。。。。。
第310条~第319条指令为第31页(对应虚存地址为[310,319]);
按以上方式,用户指令可组成32页。
(3) 计算并输出下属算法在不同内存容量下的命中率。
1) 先进先出的算法(FIFO);
2) 最近最少使用算法(LRU);
3) 最佳淘汰算法(OPT);
4) 最少访问页面算法(LFR);
其中3)和4)为选择内容 开 始 生成地址流 输入算法号S 1≤S≤4 形成地址页号 用户内存空间msize=2 Msize≤32 OPT() FIFO() LRU() LFU() Msize加1 S=? 是否用其他算法继续 结 束 N Y 1 2 3 4 Y N 提示出错,重新输入 三. 系统框图 四.页面置换算法程序代码:
#include<stdio.h> #include<string.h> #include<iostream.h> const int MAXSIZE=1000;//定义最大页面数 const int MAXQUEUE=3;//定义页框数 typedef struct node { int loaded; int hit; }page; page pages[MAXQUEUE]; //定义页框表 int queue[MAXSIZE]; int quantity; //初始化结构函数 void initial() { int i; for(i=0;i<MAXQUEUE;i++) { pages[i].loaded=-1; pages[i].hit=0; } for(i=0;i<MAXSIZE;i++) { queue[i]=-1; } quantity=0; } //初始化页框函数 void init() { int i; for(i=0;i<MAXQUEUE;i++) { pages[i].loaded=-1; pages[i].hit=0; } } //读入页面流 void readData() { FILE *fp; char fname[20]; int i; cout<<“请输入页面流文件名:“; cin>>fname; if((fp=fopen(fname,“r“))==NULL) { cout<<“错误,文件打不开,请检查文件名“; } else { while(!feof(fp)) { fscanf(fp,“%d “,&queue[quantity]); quantity++; } } cout<<“读入的页面流:“; for(i=0;i<quantity;i++) { cout<<queue[i]<<“ “; } } //FIFO调度算法 void FIFO() { int i,j,p,flag; int absence=0; p=0; cout<<endl<<“----------------------------“<<endl; cout<<“先进先出调度算法(FIFO)页面调出流:“; for(i=0;i<quantity;i++) { flag=0; for(j=0;j<MAXQUEUE;j++) { if(pages[j].loaded==queue[i]) { flag=1; } } if(flag==0) { if(absence>=MAXQUEUE) { cout<<pages[p].loaded<<“ “; } pages[p].loaded=queue[i]; p=(p+1)%MAXQUEUE; absence++; } } absence-=MAXQUEUE; cout<<endl<<“总缺页数:“<<absence<<endl; } //最近最少使用调度算法(LRU) void LRU() { int absence=0; int i,j; int flag; for(i=0;i<MAXQUEUE;i++) { pages[i].loaded=queue[i]; } cout<<endl<<“---------------------“<<endl; cout<<“最近最少使用调度算法(LRU)页面流:“; for(i=MAXQUEUE;i<quantity;i++) { flag=-1; for(j=0;j<MAXQUEUE;j++) { if(queue[i]==pages[j].loaded) { flag=j; } } //CAUTION pages[0]是队列头 if(flag==-1) { //缺页处理 cout<<pages[0].loaded<<“ “; for(j=0;j<MAXQUEUE-1;j++) { pages[j]=pages[j+1]; } pages[MAXQUEUE-1].loaded=queue[i]; absence++; } else { //页面已载入 pages[quantity]=pages[flag]; for(j=flag;j<MAXQUEUE-1;j++) { pages[j]=pages[j+1]; } pages[MAXQUEUE-1]=pages[quantity]; } } cout<<endl<<“总缺页数:“<<absence<<endl; } //显示 void version() { cout<<“ /*******************虚拟存储管理器的页面调度****************/“<<endl; cout<<endl; } void main() { version(); initial(); readData(); FIFO(); init(); LRU(); init(); init(); } 四. 运行结果 运行程序前先新建一个页面流文件文件(格式为*.txt),在文件中存储的是一系列页面号(页面号用整数表示,用空格作为分隔符),用来模拟待换入的页面。例如:
14 5 18 56 20 25 6 3 8 17 实验四 磁盘调度 一、 实验目的:
磁盘是高速、大容量、旋转型、可直接存取的存储设备。它作为计算机系统的辅助存储器,担负着繁重的输入输出工作,在现代计算机系统中往往同时会有若干个要求访问磁盘的输入输出要求。系统可采用一种策略,尽可能按最佳次序执行访问磁盘的请求。由于磁盘访问时间主要受寻道时间T的影响,为此需要采用合适的寻道算法,以降低寻道时间。本实验要求学生模拟设计一个磁盘调度程序,观察调度程序的动态运行过程。通过实验让学生理解和掌握磁盘调度的职能。
二、 实验题目:
模拟电梯调度算法,对磁盘进行移臂操作 三、 提示及要求:
1、 假设磁盘只有一个盘面,并且磁盘是可移动头磁盘。
2、 磁盘是可供多个进程共享的存储设备,但一个磁盘每个时刻只能为一个进程服务。当有进程在访问某个磁盘时,其它想访问该磁盘的进程必须等待,直到磁盘一次工作结束。当有多个进程提出输入输出请求而处于等待状态时,可用电梯调度算法从若干个等待访问者中选择一个进程,让它访问磁盘。为此设置“驱动调度”进程。
3、 由于磁盘与处理器是并行工作的,所以当磁盘在为一个进程服务时,占有处理器的其它进程可以提出使用磁盘(这里我们只要求访问磁道),即动态申请访问磁道,为此设置“接受请求”进程。
4、 为了模拟以上两个进程的执行,可以考虑使用随机数来确定二者的允许顺序,程序结构图参考附图:
5、 “接受请求”进程建立一张“进程请求I/O”表,指出等待访问磁盘的进程要求访问的磁道,表的格式如下:
进程名 要求访问的磁道号 6、 “磁盘调度”的功能是查“请求I/O”表,当有等待访问的进程时,按电梯调度算法(SCAN算法)从中选择一个等待访问的进程,按其指定的要求访问磁道。SCAN算法参考课本第九章。算法模拟框图略。
7、 图1中的“初始化”工作包括:初始化“请求I/O”表,设置置当前移臂方向;
当前磁道号。并且假设程序运行前“请求I/O”表中已有若干进程(4~8个)申请访问相应磁道。
四、 实验报告:
1、 实验题目。
2、 程序中用到的数据结构及其说明。
3、 打印源程序并附注释。
4、 实验结果内容如下:打印“请求I/O”表,当前磁道号,移臂方向,被选中的进程名和其要求访问的磁道,看是否体现了电梯调度(SCAN)算法。
5、 体会与问题。
五、 附图:
开始 初始化 磁盘调度 随机数>1/2 继续? 接受请求 输入在[0,1]区间内的随机数 结束 六.磁盘调度的程序代码:
#include<iostream> #include<cmath> using namespace std; typedef struct node { int data; struct node *next; }Node; void main() { void fcfs(Node *,int,int);//声明先来先服务函数FCFS void sstf(Node *,int,int);//声明最短寻道时间优先函数SSTF void scan(Node *,int,int);//声明扫描函数SCAN void print(Node *); //输出链表函数 Node *head,*p,*q; //建立一个链表 int it,c=0,f,s; //c为链表长度,f是开始的磁道号,s是选择哪个算法 head=(Node *)malloc(sizeof(Node)); head->next=NULL; q=head; cout<<“ /**************磁盘调度算法***************/“<<endl; cout<<endl; cout<<“新建一个单链表,以0作为结束标志:“; cin>>it; while(it!=0) { p=(Node *)malloc(sizeof(Node)); p->next=NULL; p->data=it; q->next=p; q=p; cin>>it; c++; } cout<<“从几号磁道开始:“; cin>>f; //f为磁道号 print(head); cout<<“链表长度为:“<<c<<endl; cout<<“1、先来先服务算法FCFS“<<endl; cout<<“2、最短寻道时间优先算法SSTF“<<endl; cout<<“3、电梯调度算法(扫描算法SCAN)“<<endl; cout<<“0、退出“<<endl; cout<<“请选择:“; cin>>s; while(s!=0) { switch(s) { case 1:cout<<“你选择了:先来先服务算法FCFS“<<endl; fcfs( head,c,f); break; case 2:cout<<“你选择了:最短寻道时间优先算法SSTF“<<endl; sstf( head,c,f); break; case 3:cout<<“你选择了:电梯调度算法(扫描算法SCAN)“<<endl; scan( head,c,f); break; } cout<<“退出请选0,继续请选1,2,3:“; cin>>s; } } /***********************************************************/ void fcfs(Node *head,int c,int f)//先来先服务算法 { void print(Node *); Node *l;//*m,*n; float num=0; //num为平均寻道长度 l=head->next; for(int i=0;i<c;i++) { num+=abs(l->data-f); f=l->data; l=l->next; } num=num/c; cout<<“先来先服务的寻道顺序是:“<<endl; print(head); cout<<“平均寻道长度:“<<num<<endl; } /*****************************************************************/ void sstf(Node *head,int c,int f)//最短寻道时间优先算法 { void print(Node *); Node *p,*q,*r,*s,*l,*m; l=(Node *)malloc(sizeof(Node)); l->next=NULL; m=l; q=head; p=head->next; s=head; r=head->next; float num=0; for(int i=0;i<c;i++) { int min=abs(f-r->data); for(int j=0;j<c-i-1;j++) { p=p->next; q=q->next; if(abs(f-p->data)<min) { min=abs(f-p->data); r=p; s=q; } } num+=abs(f-r->data); f=r->data; s->next=r->next; r->next=NULL; m->next=r; m=r; q=head; p=head->next; s=head; r=head->next; } num=num/c; cout<<“最短寻道时间优先顺序是:“<<endl; print(l); cout<<“平均寻道长度:“<<num<<endl; } /***************************************************************/ void scan(Node *head,int c,int f)//扫描算法(电梯调度算法) { void print(Node *); int min,max,i=0,j=0; float num=0; Node *p,*q,*r,*s,*m,*n,*x,*y; r=(Node *)malloc(sizeof(Node));//存放比开始磁道小的磁道 r->next=NULL; s=r; m=(Node *)malloc(sizeof(Node));//存放比开始磁道大的磁道 m->next=NULL; n=m; x=(Node *)malloc(sizeof(Node)); x->next=NULL; y=x; q=head; p=head->next; while(p->next!=NULL) { if(p->data-f>0) { q->next=p->next; p->next=NULL; n->next=p; n=p; p=q->next; i++; } else { q->next=p->next; p->next=NULL; s->next=p; s=p; p=q->next; j++; } } if(p->data>=f) { n->next=p; n=p; i++; } else { s->next=p; s=p; j++; } q=r; //对比开始磁道小的磁道排序 p=r->next; while(q->next->next!=NULL) { q=q->next; p=q->next; max=q->data; while(p->next!=NULL) { if(p->data>max) { max=p->data; p->data=q->data; q->data=max; max=q->data; } p=p->next; } if(p->data>max) { max=p->data; p->data=q->data; q->data=max; max=q->data; } } //print(r); q=m; p=m->next; while(q->next->next!=NULL) { q=q->next; p=q->next; min=q->data; while(p->next!=NULL) { if(p->data<min) { min=p->data; p->data=q->data; q->data=min; min=q->data; } p=p->next; } if(p->data<min) { min=p->data; p->data=q->data; q->data=min; min=q->data; } } //print(m); x=m; p->next=r->next; y=x->next; while(y->next!=NULL) { num+=abs(f-y->data); f=y->data; y=y->next; } num+=abs(f-y->data); num=num/c; cout<<“扫描算法的顺序是:“<<endl; print(x); cout<<“平均寻道长度为:“<<num<<endl; } /*****************************************************/ void print(Node *head) //输出链表 { Node *p; p=head->next; cout<<“单链表显示:“; if(p==NULL) { cout<<“单链表为空:“; } else if(p->next==NULL) { cout<<p->data; } else { while(p->next!=NULL) { cout<<p->data<<“->“; p=p->next; } cout<<p->data<<endl; } } 七.运行结果:
相关热词搜索:
- 范文大全
- 说说大全
- 学习资料
- 语录
- 生肖
- 解梦
- 十二星座
-
主题党日活动交流发言8篇
主题党日活动交流发言8篇主题党日活动交流发言篇13月13日,东城区党史学习教育动员大会召开。市委
【活动总结】 日期:2022-12-23
-
2022年4月主题党日活动记录范文15篇
2022年4月主题党日活动记录范文15篇2022年4月主题党日活动记录范文篇1一个崇尚阅读的民族,必然精神饱满、意气风发、活力四射。习近平总书记强调:“学习
【活动总结】 日期:2022-08-01
-
家乡赋|最美的家乡赋
家乡赋 孙传志 今安康市,白河双丰镇,吾之家乡也。三环沃土,山水环抱。其北依山,山系五岭,山
【调研报告】 日期:2020-04-01
-
【人教版1-6年级数学上册知识点精编】1-6年级数学人教版教材
人教版二年级数学上册知识点汇总第一单元长度单位一、米和厘米1、测量物体的长度时,要用统一的标准去测量
【调研报告】 日期:2020-11-08
-
党支部1-12月全年主题党日活动计划表
2022年党支部主题党日活动计划表序号活动时间活动方式活动内容12022年1月专题学习研讨集中观看2022年新年贺词,积极开展学习研讨交流。组织生活会组织党员认真对照党章...
【活动总结】 日期:2022-10-14
-
2022年2月份主题党日活动记录5篇
2022年2月份主题党日活动记录5篇2022年2月份主题党日活动记录篇1尊敬的党组织:在今年的开学初,本人积极参加教研室组织的教研活动,在学校教研员的指
【活动总结】 日期:2022-08-12
-
少先队的光荣历史故事 队前教育-光辉历程
2017-2018学年队前教育1光辉历程一、劳动童子团1924——1927二、三十年代年的中国是一个
【法律文书】 日期:2020-06-23
-
2023年平安校园建设方案13篇
平安校园建设方案“平安校园”创建工作,我们幼儿园全体教职员工一直把它当作头等大事来抓。领导高度重视,以“平安校园”创建活动为抓手,建立和规范校园安全工作机制
【规章制度】 日期:2023-11-02
-
医院最佳主题党日活动11篇
医院最佳主题党日活动11篇医院最佳主题党日活动篇1 医院最佳主题党日活动篇2为隆重纪念中国共产党成立100周年,进一步巩固党的群众路线教育实践活动成果,切实
【活动总结】 日期:2022-10-29
-
主题党日活动记录202210篇
主题党日活动记录202210篇主题党日活动记录2022篇12021年是中国共产党成立100周年,为广泛开展爱国主义宣传教育,铭记党的历史,讴歌党的光辉历程,
【活动总结】 日期:2022-08-02
-
一年级新学期目标简短_一年级学生新学期打算
新学期到了,我是一年级下册的小学生了。 上课的时候,我要认真学习,不做小动作,认真听讲。我要认真学习,天天向上,努力学习,耳朵要听老师讲课,眼睛要瞪得大大的看老...
【简历资料】 日期:2019-10-26
-
《国行公祭,为佑世界和平》课文原文阅读_国行公祭为佑世界和平每段段意
国行公祭,为佑世界和平钟声“国行公祭,法立典章。铸兹宝鼎,祀我国殇。”侵华日军南京大屠杀遇难同胞纪念
【简历资料】 日期:2020-11-28
-
[信访复查复核制度作用探讨]信访复查复核有用吗
作为我国特有的一项制度,信访制度的出现并长期存在不是偶然的,虽然一些法学专家认为信访制度具有“人治”
【职场指南】 日期:2020-02-16
-
[党员干部2019年主题教育个人问题检视清单及整改措施2篇] 党员干部
2019年主题教育问题检视清单及整改措施根据主题教育领导小组办公室《关于认真做好主题教育检视问题整改
【求职简历】 日期:2019-11-08
-
网络维护工作内容_(精华)国家开放大学电大专科《网络系统管理与维护》形考任务1答案
国家开放大学电大专科《网络系统管理与维护》形考任务1答案形考任务1理解上网行为管理软件的功能【实训目
【职场指南】 日期:2020-07-17
-
民族团结的素材资料13篇
民族团结的素材资料13篇民族团结的素材资料篇1研究进一步推进新疆社会稳定和长治久安工作。会议指出,要全面贯彻执行党的民族政策,把民族团结作为各族人民的生命线
【简历资料】 日期:2022-08-16
-
红旗颂朗诵稿原文【《红旗颂》朗诵词】
《红旗颂》朗诵词 女:晴空万里,红旗飘扬, 六十载风云,我们昂首阔步。 男:六十个春秋,
【职场指南】 日期:2020-02-16
-
党委会与局长办公会的区别_局长办公会制度
为进一步加强xxx局工作的规范化、制度化建设,提高行政效能,规范议事程序,特制定本制度。一、会议形式1、局长办公会议由局长、副局长参加。由局长召集和主持。根据工作需要...
【求职简历】 日期:2019-07-30
-
如何凝心聚力谋发展【坚定信心谋发展凝心聚力促跨越】
当前,清河正处于在苏北实现赶超跨越基础上全面腾飞的战略机遇期,处于在全市率先实现全面小康基础上率先实
【简历资料】 日期:2020-03-17
-
《铁拳砸碎“黑警伞”》警示教育片观后感
影片深刻剖析了广西北海市公安局海西派出所原所长张枭杰蜕变堕落的轨迹。观看警示教育片后,做为一名党员教
【简历资料】 日期:2020-08-17
-
2022年度县委书记在全县安全隐患大排查大整治工作会议上的讲话【完整版】
县委书记在全县安全隐患大排查大整治工作会议上的讲话同志们:今天,我们召开全县安全隐患大排查大整治工作会议,主要任务是深入学习贯彻******重要讲话重要指示批示精神,传...
【其他范文】 日期:2022-11-05
-
物理探究杠杆平衡条件 探究杠杆的平衡条件学案:沪粤版八年级下册物理
6 5探究杠杆的平衡条件一、自主学习(一)目标导读1 通过参与科学探究活动,能得出杠杆的平衡条件2
【口号大全】 日期:2021-05-28
-
朗诵晚会主持稿_简短诗朗诵报幕词
开场:女:各位来宾,亲爱的朋友们,晚上好!男:欢迎大家来到《开心军团》,参加《同一蓝天下》爱心主题晚会,愿您在这里度过一个温馨的夜晚。女:浩瀚苍穹、蔚蓝天空,孕育...
【节日庆典】 日期:2019-10-03
-
深化“三个以案”警示教育心得体会
根据局机关党委关于“三个以案”警示教育活动的总体部署和安排,现联系个人实际汇报学习体会。不妥之处,敬
【毕业论文】 日期:2020-07-10
-
_最新某区教育学校“双减”加强中小学生中小学生作业、睡眠、手机、读物、体质等“五项管理”实施方案
某区加强中小学生“五项管理”工作方案为贯彻落实教育部、省教育厅和市教育局对中小学生作业、睡眠、手机、
【口号大全】 日期:2021-08-02
-
纪检监察工作公文写作提纲 (30例)【完整版】
1 切实做到“六个转变”推动派驻纪检监察工作高质量发展“一脱了之”向“脱而不离”转变。“大水漫灌”向“精准滴灌”转变。“按部就班”向“出其不意”转变。“结果导向”向...
【其他范文】 日期:2022-09-11
-
2022在2022年市食品安全工作会议上的讲话
下面是小编为大家整理的2022在2021年市食品安全工作会议上的讲话
【其他范文】 日期:2022-08-20
-
2022年7月1日这一天,我观看了庆祝建党100周年电视直播,新潮澎湃,
新潮,汉语词语,拼音是xīncháo,意思是指新的社会风气或思潮。出自鲁迅《热风·儿歌的“反动”》,以下是为大家整理的关于2021年7月1日这一天,我观看了庆祝建党100周年电视...
【其他范文】 日期:2022-08-30
-
幼儿园托班宝宝评语10篇
幼儿园托班宝宝评语1、你每天总是愉快的来到幼儿园,在幼儿园里,能够和小朋友们友好相处;你还能把学到的本领,用响亮的声音告诉大家,像一个小小表演家呢!每次
【评语寄语】 日期:2023-09-09
-
2022年在全市住建领域环保整改推进会上的讲话
下面是小编为大家整理的2022年2021年在全市住建领域环保整改推进会上的讲话
【其他范文】 日期:2022-08-09
-
理论中心组学习总体国家安全观发言材料9篇
理论中心组学习总体国家安全观发言材料9篇理论中心组学习总体国家安全观发言材料篇1(八)深入学习贯彻中央以及省的重要会议和文件精神深入学习贯彻年度内中央以
【发言稿】 日期:2022-08-04
-
军转座谈会交流发言4篇
军转座谈会交流发言4篇军转座谈会交流发言篇1大家好,我叫贺丽,2015届选调生,来自康定市委组织部,现在省委编办跟班学习。今天,非常荣幸向大家汇报我的学习收
【发言稿】 日期:2022-10-27
-
12岁生日小寿星发言4篇
12岁生日小寿星发言4篇12岁生日小寿星发言篇1各位来宾、各位朋友:大家好!今天,我们欢聚在这里,共同庆祝**十二周岁生日。首先,我代表**的父母以
【发言稿】 日期:2022-07-31
-
党内警告处分表态发言14篇
党内警告处分表态发言14篇党内警告处分表态发言篇1尊敬的各位领导、同事们:大家上午好!刚才会上宣布了党委关于我任职的决定,我首先衷心感谢党委的信任和
【发言稿】 日期:2022-09-13
-
党内警告处分党员讨论发言3篇
党内警告处分党员讨论发言3篇党内警告处分党员讨论发言篇1大家好!作为新时期的一名大学生,认真学习、深刻领会、全面贯彻省党代会精神,是当前和今后一个时期重
【发言稿】 日期:2022-08-07
-
廉政大会总结发言稿7篇
廉政大会总结发言稿7篇廉政大会总结发言稿篇1各位领导,同志们:根据会议安排,我就党风廉政建设工作做表态发言,不妥之处,请批评指正。一、提高认识,切实
【发言稿】 日期:2022-10-30
-
【企业疫情风险控制方案】 2020企业复工疫情方案
企业疫情风险控制方案2020新冠病毒肺炎疫情防控工作总结汇报3篇 关于新型冠状病毒感染的肺炎疫
【演讲稿】 日期:2020-02-27
-
被约谈的表态发言8篇
被约谈的表态发言8篇被约谈的表态发言篇1各位领导、各位党员大家好:这天我能站在鲜红的党旗下,
【发言稿】 日期:2022-12-24
-
破冰提能大讨论个人发言4篇
破冰提能大讨论个人发言4篇破冰提能大讨论个人发言篇1党史学习教育开展以来,我坚持读原著、学原文、悟原理。今天,根据会议安排,现在我就“学史明理”主题谈几点个
【发言稿】 日期:2022-10-09
-
巡察整改专题民主生活会总结发言8篇
巡察整改专题民主生活会总结发言8篇巡察整改专题民主生活会总结发言篇1按照区委统一部署和纪监委、巡察办关于召开党史学习教育专题组织生活会的工作安排,近期我紧贴
【发言稿】 日期:2022-10-12
-
2023年中国行政区划调整方案(设想优秀3篇
中国行政区划调整方案(设想优秀民政部第二次行政区划研讨会会议内容一、缩省的意义与原则1.意义1)利于减少中间层次中国行政区划层级之多为世界之最,既使管理成本
【周公解梦】 日期:2024-02-20
-
学习周永开先进事迹心得体会3篇
学习周永开先进事迹心得体会【一】通过学习周永开老先生先进事迹后,结合自己工作思考,感慨万千。同样作为
【格言】 日期:2021-04-10
-
XX老干局推进党建与业务深度融合发展工作情况调研报告:党建调研报告
XX老干局推进党建与业务深度融合 发展工作情况的调研报告 党建工作与业务工作融合发展始终是一个充满生
【成语大全】 日期:2020-08-28
-
最满意的三项工作200字【最新党办公务员副主任提拔考察个人三年思想工作总结报告】
党办公务员个人三年工作总结近三年来,本人在组织、领导的关心指导和同事们的团结协作下,尽快完成主角的转
【格言】 日期:2021-02-26
-
中国共产党第三代中央领导集体的卓越贡献
中国共产党第三代中央领导集体的卓越贡献 --------------继往开来铸就辉煌 【摘要】改
【成语大全】 日期:2020-03-20
-
信息技术2.0能力点 [全国中小学教师信息技术应用能力提升工程试题题库及参考答案「精编」]
全国中小学教师信息技术应用能力提升工程试题题库及答案(复习资料)一、判断题题库(A为正确,B为错误)
【格言】 日期:2020-11-17
-
党建工作运行机制内容有哪些_构建基层党建工作运行机制探讨
党的基层组织是党在社会基层组织中的战斗堡垒,是党的全部工作和战斗力的基础。加强和改进县级以下各类党的
【经典阅读】 日期:2020-01-22
-
集合推理_七,推理与集合
七推理与集合1 期中考试数学成绩出来了,三个好朋友分别考了88分,92分,95分。他们分别考了多少分
【名人名言】 日期:2020-12-18
-
电大现代教育原理_最新国家开放大学电大《现代教育原理》形考任务2试题及答案
最新国家开放大学电大《现代教育原理》形考任务2试题及答案形考任务二一、多项选择题(共17道试题,共3
【成语大全】 日期:2020-07-20
-
2023年和儿媳妇在一起幸福的句子3篇
和儿媳妇在一起幸福的句子1、假如人生不曾相遇,我还是那个我,偶尔做做梦,然后,开始日复一日的奔波,淹没在这喧嚣的城市里。我不会了解,这个世界还有这样的一个你
【格言】 日期:2023-11-10
-
关于三农工作重要论述心得体会3篇
关于三农工作重要论述心得体会3篇关于三农工作重要论述心得体会篇1习近平总书记指出:“建设现代化国家离不开农业农村现代化,要继续巩固脱贫攻坚成果,扎实推进乡村
【学习心得体会】 日期:2022-10-29
-
【福生庄隧道坍塌处理方案】 福生庄隧道在哪里
(呼和浩特铁路局大包电气化改造工程指挥部,内蒙古呼和浩特010050)摘要:文章介绍了福生庄隧道
【学习心得体会】 日期:2020-03-05
-
五个一百工程阅读心得体会13篇
五个一百工程阅读心得体会13篇五个一百工程阅读心得体会篇1凡益之道,与时偕行。在全国网络安全和信
【学习心得体会】 日期:2022-12-07
-
城管系统警示教育心得体会9篇
城管系统警示教育心得体会9篇城管系统警示教育心得体会篇1各党支部要召开多种形式的庆七一座谈会,组织广大党员进行座谈,回顾党的光辉历程,畅谈党的丰功伟绩,
【学习心得体会】 日期:2022-10-09
-
发展对象培训主要内容10篇
发展对象培训主要内容10篇发展对象培训主要内容篇1怀着无比激动的心情,我有幸参加了__新区区委党校20__年第四期(区级机关)党员发展对象培训班。这次的学习
【培训心得体会】 日期:2022-09-24
-
扶眉战役纪念馆心得体会11篇
扶眉战役纪念馆心得体会11篇扶眉战役纪念馆心得体会篇1有那么一段历史,低诉着血和泪的故事,慢慢地,随岁月老去;有那么一群人,放弃了闲逸的人生,辗转奔波中
【学习心得体会】 日期:2022-08-03
-
2022年全国检察长会议心得7篇
2022年全国检察长会议心得7篇2022年全国检察长会议心得篇1眼睛是心灵上的窗户,我们通过眼睛才能看到世间万物,才能看到眼前这美好的一切。拥有一双明亮的眼
【学习心得体会】 日期:2022-10-31
-
全面从严治党的心得体会800字7篇
全面从严治党的心得体会800字7篇全面从严治党的心得体会800字篇1中国特色社会主义是我们党领导
【学习心得体会】 日期:2022-12-14
-
2月教师党员个人思想汇报5篇
2月教师党员个人思想汇报敬爱的党组织:最近这一个月的时间对于我来说是极不平凡的,在这段时间里我认真学习了文化部网上党校的相关内容,经过长达40小时的
【教师心得体会】 日期:2023-10-15
-
矫正心得体会6篇
矫正心得体会6篇矫正心得体会篇1今天,是自己出监后第一次参加阳光中途之家组织的社区矫正方面的教育
【学习心得体会】 日期:2022-12-24
-
2024年主题教育民主生活会批评与自我批评意见(38条)(范文推荐)
2023年主题教育民主生活会六个方面个人检视、相互批评意见:1 理论学习系统性不强。学习习近平新时代中国特色社会主义思想不深不透,泛泛而学的时候多,深学细照的时候少,特...
【邓小平理论】 日期:2024-03-19
-
2024年交流发言:强化思想理论武装,增强奋进力量(完整)
习近平总书记指出:“一个民族要走在时代前列,就一刻不能没有理论思维,一刻不能没有思想指引。”党的十八大以来,伴随着新时代中国特色社会主义思想在实践中形成发展的历程...
【三个代表】 日期:2024-03-19
-
2024年度镇年度县乡人大代表述职评议活动总结
xx镇20xx年县乡人大代表述职评议活动总结为响应县级人大常委会关于开展县乡两级人大代表述职评议活动,进一步激发代表履职活力,加强代表与人民群众的联系,提高依法履职水平...
【马克思主义】 日期:2024-03-19
-
“千万工程”经验学习体会(研讨材料)
“千万工程”是总书记在浙江工作时亲自谋划、亲自部署、亲自推动的一项重大决策,也是习近平新时代中国特色社会主义思想在之江大地的生动实践。20年来,“千万工程”先后经历...
【三个代表】 日期:2024-03-19
-
2024年在市政协机关工作总结会议上讲话
同志们:刚才,XX同志对市政协机关20XX年工作进行了很好的总结,很精炼,很到位,可以感受到去年机关工作确实可圈可点。XX同志宣读了表彰决定,机关优秀人员代表、先进集体代...
【邓小平理论】 日期:2024-03-18
-
在全区防汛防涝动员暨河长制工作推进会上讲话提纲【完整版】
区长,各位领导,同志们:汛期已经来临,我区城区防涝工作面临强大考验,形势不容乐观。年初,区城区防涝排渍指挥部已经召开专题调度会,修订完善应急预案,建立网格化管理机...
【马克思主义】 日期:2024-03-18
-
2024年镇作风整治工作实施方案(完整文档)
XX镇作风整治工作实施方案为深入贯彻落实党的二十大精神及省市区委深化作风建设的最新要求,突出重点推进干部效能提升,坚持不懈推动作风整治工作纵深发展,根据《关于印发《2...
【毛泽东思想】 日期:2024-03-18
-
2024市优化法治化营商环境规范涉企行政执法实施方案【优秀范文】
xx市优化法治化营商环境规范涉企行政执法实施方案为持续优化法治化营商环境,激发市场主体活力和社会创造力,规范行政执法行为,创新行政执法方式,提升行政执法质效,着力解...
【毛泽东思想】 日期:2024-03-18
-
2024年度关于开展新一轮思想状况摸底排查工作通知(完整)
关于开展新一轮思想状况摸底排查工作的通知为深入贯彻落实关于各地开展干部职工思想状况大摸底大排查情况上的批示要求和改革教育第二次调度会议精神,有针对性做好队伍教育管...
【三个代表】 日期:2024-03-18
-
2024年公路养护中心主任典型事迹材料(完整文档)
“中心的工作就是心中的事业”——公路养护中心主任典型事迹材料**,男,1976年6月出生,1993年参加工作,2000年4月调入**区交通运输局工作,大学本科学历,中共党员,现任**...
【马克思主义】 日期:2024-03-17