C语言模拟操作系统运行课程设计_第1页
C语言模拟操作系统运行课程设计_第2页
C语言模拟操作系统运行课程设计_第3页
C语言模拟操作系统运行课程设计_第4页
C语言模拟操作系统运行课程设计_第5页
已阅读5页,还剩44页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、操作系统课程设计报告时间:2010-12-202010-12-31地点:信息技术实验中心计算机 专业2008级x班xx号xx2010-12-31目录一 课程设计的目的和意义3二 进程调度算法模拟41 设计目的42 设计要求43 时间片轮转算法模拟44 先来先服务算法模拟9三 主存空间的回收与分配141 设计目的142 设计要求143 模拟算法的实现15四 模拟dos文件的建立和使用261 设计目的262 设计要求263 模拟算法的实现27五 磁盘调度381 设计目的382 设计要求383 模拟算法的实现38六 总结49一、课程设计的目的和意义本次操作系统课程设计的主要任务是进行系统级的程序设计

2、。本课程设计是操作系统原理课程的延伸。通过该课程设计,使学生更好地掌握操作系统各部分结构、实现机理和各种典型算法,加深对操作系统的设计和实现思路的理解,培养学生的系统设计和动手能力,学会分析和编写程序。课程设计的实施将使学生在以下几个方面有所收获:(1)加深对操作系统原理的理解,提高综合运用所学知识的能力;(2)培养学生自主查阅参考资料的习惯,增强独立思考和解决问题的能力;(3)通过课程设计,培养严谨的科学态度和协作精神。二:进程调度算法模拟1 设计目的(1)要求学生设计并实现模拟进程调度的算法:时间片轮转及先来先服务。(2)理解进程控制块的结构。(3)理解进程运行的并发性。(4)掌握进程调度

3、算法。2 设计要求在多道程序运行环境下,进程数目一般多于处理机数目,使得进程要通过竞争来使用处理机。这就要求系统能按某种算法,动态地把处理机分配给就绪队列中的一个进程,使之运行,分配处理机的任务是由进程调度程序完成的。一个进程被创建后,系统为了便于对进程进行管理,将系统中的所有进程按其状态,将其组织成不同的进程队列。于是系统中有运行进程队列、就绪队列和各种事件的进程等待队列。进程调度的功能就是从就绪队列中挑选一个进程到处理机上运行。进程调度的算法有多种,常用的有优先级调度算法、先来先服务算法、时间片轮转算法。进程是程序在处理机上的执行过程。进程存在的标识是进程控制块(pcb),进程控制块结构如

4、下:typedef struct node char name10; /* 进程标识符 */ int prio; /* 进程优先数 */ int round; /* 进程时间轮转时间片 */ int cputime; /* 进程占用 cpu 时间*/ int needtime; /* 进程到完成还需要的时间*/ int count; /* 计数器*/ char state; /* 进程的状态*/ struct node *next /*链指针*/ pcb; 系统创建一个进程,就是由系统为某个程序设置一个pcb,用于对该进程进行控制和管理,进程任务完成,由系统收回其pcb,该进程便消亡。每个进程

5、可以有三个状态:运行状态、就绪状态和完成状态。用c语言、c+或者java语言编写一个程序实现进程调度的算法,模拟进程调度的过程,加深对进程控制块概念和进程调度算法的理解。本任务要求完成时间片轮转及先来先服务两个算法。3.时间片轮转算法完成进程的调度3.1设计要求:(1)进程的调度采用时间片轮转算法。(2)设计三个链队列,分别用来表示运行队列、就绪队列和完成队列。(3)用户输入进程标识符以及进程所需的时间,申请空间存放进程 pcb信息。(4)输出的格式和上面的运行结果分析中的格式相同。时间片轮转调度,具体做法是调度程序每次把 cpu 分配给就绪队列首进程使用一个时间片。当这个时间片结束时,就强迫

6、一个进程让出处理器,让它排列到就绪队列的尾部,等候下一轮调度。实现这种调度要使用一个间隔时钟。当一个进程开始运行时,就将时间片的值置入间隔时钟内,当发生间隔时钟中断时,就表明该进程连续运行的时间已超过一个规定的时间片。此时,中断处理程序就通知处理器调度进行处理器的切换工作。3.2.时间片轮转算法主要思想:在计算机中系统将所有的就绪进程按先来先服务的原则排成一个队列,每次调度时,把cpu分配给队首进程,并令其执行一个时间片。时间片的大小从几ms到几百ms。当执行的时间片用完,由一个计时器发出时钟中断请求,调度程序便据此信号来停止该进程的执行,并将它送往就绪队列的末尾;然后再把处理机分配给就绪队列

7、中给定的时间内均能获得一时间片的处理机执行时间。3.3算法的实现1.数据结构及变量说明 typedef struct pcb char name10; /进程标识符 int parrivetime; /到达时间 int pruntime; /估计运行时间 int round; /进程时间轮转时间片 int cputime; /进程占用cpu时间 int needtime; /进程到完成还要的时间 int count; /计数器 char state; /进程的状态 struct pcb *next; /链指针pcb;pcb *finish,*ready,*tail,*run; /队列指针pcb

8、 head_input; int n; /进程数2.完成功能的主要函数void roundrun()/时间片轮转法函数3.时间片轮转的主要算法功能及注释:void insert2(pcb *p2)/轮转法插入函数 tail-next=p2; /将新的pcb插入在当前就绪队列的尾 tail=p2; p2-next=null;void create2()/轮转法创建进程pcb pcb *p; int i,time,n; char na10; ready=null; finish=null; run=null; printf(输入进程名及所需时间n); for(i=1;iname,na); p-cp

9、utime=0; p-needtime=time; p-count=0; /计数器 p-state=w; p-round=3; if(ready!=null) insert2(p); else p-next=ready; ready=p; tail=p; system(cls); printf( 轮转法输出n); printf(*n); prt(); /输出进程pcb信息 run=ready; /将就绪队列的第一个进程投入运行 ready=ready-next; run-state=r;void roundrun()/时间片轮转法 while(run!=null) run-cputime=ru

10、n-cputime+1; run-needtime=run-needtime-1; run-count=run-count+1; if(run-needtime=0)/运行完将其变为完成态,插入完成队列 run-next=finish; finish=run; run-state=f; run=null; if(ready!=null) firstin(); /就绪对列不空,将第一个进程投入运行 else if(run-count=run-round) /如果时间片到 run-count=0; /计数器置0 if(ready!=null) /如就绪队列不空 run-state=w; /将进程插

11、入到就绪队列中等待轮转 insert2(run); firstin(); /将就绪对列的第一个进程投入运行 prt(); /输出进程信息 4.时间片算法主要流程图如下:开始创建pcb进程,输入进程名及时间就绪队列ready!nullyrun-cputime=run-cputime+1;run-needtime=run-needtime-1;run-count=run-count+1;run-needtime=0yrun-next=finish; finish=run;run-state=f; run=null;ready!=nullyrun=ready; run-state=r;ready=r

12、eady-next;run-count=run-roundnrun-count=0;/计数器置0yready!=nullytail-next=run; tail=run;run-next=null; run-state=w; run=ready; run-state=r; ready=ready-next;输出进程信息nn结束ready!=null5.时间片算法运行结果分析如下:4.用先来先服务算法完成进程的调度4.1设计要求:(1)进程的调度采用先来先服务算法。(2)设计三个链队列,分别用来表示运行队列、就绪队列和完成队列。(3)用户输入进程标识符以及进程所需的时间,申请空间存放进程pcb信

13、息。(4)输出的格式和上面的运行结果分析中的格式相同。先来先服务:按照进程进入就绪队列的先后次序来分配处理器。先进入就绪队列的进程优先被挑选,运行进程一旦占有处理器将一直运行下去直到运行结束或被阻塞,这是一种非剥夺式调度。4.2先来先服务调度算法主要思想:此算法既可用于作业调度,也歌词用于进程调度。当作业调度中采用该算法时,每次调度都是从后备作业队列中选择一个或多个最先进入该队列的作业,将它们调入内存,为它们分配资源,创建进程,然后放入就绪队列。在进程调度中采用fcfs算法时,则每次调度是从就绪队列中选择一个最先进入该队列的进程,为之分配处理机,使之投入运行。该进程一直运行到完成或发生某事件而

14、阻塞后才放弃处理机。4.3 算法的实现1.数据结构及变量说明 typedef struct pcb char name10; /进程标识符 int parrivetime; /到达时间 int pruntime; /估计运行时间 int round; /进程时间轮转时间片 int cputime; /进程占用cpu时间 int needtime; /进程到完成还要的时间 int count; /计数器 char state; /进程的状态 struct pcb *next; /链指针pcb;pcb *finish,*ready,*tail,*run; /队列指针pcb head_input;

15、int n; /进程数2.完成功能的主要函数void execprocesslist()/先来先服务函数3.先来先服务的主要算法功能及注释:void execprocesslist() run=head_input.next; while(run!=null) run=head_input.next;/run指向对头的下一个进程 printf(开始运行 正在运行 已经运行时间 剩余时间 等 待 中 的 进程 已结束进程n); for (int j=0;jpruntime)/1000;j+)/输出每次运行的统计信息 if (0=j) printf( %s n,run-name);/到达进程开始执

16、行 printf( %s %d %d,run-name,j+1,(run-pruntime/1000)-(j+1); ready=run-next; /判断此时还有哪些进程在队列里面 while (ready!=null) printf( %s ,ready-name); ready=ready-next; printf(n); run-state=c; /将进城状态设置为执行完的状态 printf( %sn,run-name); ready=run;/将run指向下一个元素 run=run-next; head_input.next=run; delete ready;/将此进程从进程队列里

17、面删除 4.先来先服务算法主要流程图如下:ready=run-next; printf( %s %d %d,run-name,j+1,(run-pruntime/1000)-(j+1);开始run=head_input.next;run!=nullyrun=head_input.next; run-state=c; printf( %sn,run-name); ready=run; run=run-next; head_input.next=run; delete ready; j=0j=0?yprintf( %s n,run-name);ready!=nullprintf( %s ,read

18、y-name); ready=ready-next;结束5.先来先服务运行结果如下:三:主存空间的回收与分配1 设计目的主存是中央处理器能直接存取指令和数据的存储器,能否合理地利用主存,在很大程度上将影响到整个计算机系统的性能。主存分配是指在多道作业和多进程环境下,如何共享主存空间。主存回收是指当作业执行完毕或进程运行结束后将主存空间归还给系统。主存分配与回收的实现是与主存储器的管理方式有关。本次设计主要是为了帮助学生深入理解主存空间的分配与回收的几种算法。(1)掌握最先适应分配算法(2)掌握最优适应分配算法(3)掌握最坏适应分配算法2 设计要求用户提出内存空间请求,系统根据申请者要求,按照最

19、先适应分配算法的分配策略分析内存空间的使用情况,找出能满足请求的空闲区,分给申请者,当程序执行完毕时,系统要收回它所占用的内存空间。建立空闲数据文件,空闲区数据文件包括若干行,每行有两个字段:起始地址、内存块大小(均为整数),各字段以逗号隔开。下面是一个空闲区数据文件的示例:0,10 10,08 18,10 28,06 34,10 44,09 读取空闲区数据文件,建立空闲区表并在屏幕上显示空闲内存状态,空闲区表记录了可供分配的空闲内存的起始地址和大小,用标志位指出该分区是否是未分配的空闲区。接收用户的内存申请,格式为:作业名、申请空间的大小。按照内存分配算法中的一种方法选择一个空闲区,分割并分

20、配,修改空闲区表,填写内存已分配区表(起始地址、长度、标志位),其中标志位的一个作用是指出该区域分配给哪个作业。进程结束后回收内存。本次设计要求完成如下算法:(1)设计一个内存分配回收的程序使用最先适应分配算法(2)设计一个内存分配回收的程序使用最优适应分配算法(3)设计一个内存分配回收的程序使用最坏适应分配算法用户提出内存空间请求,系统根据申请者要求,选择上述算法的一种分配策略分析内存空间的使用情况,找出合适的空闲区,分给申请者,当进程执行完毕时,系统收回它所占用的内存空间。创建空闲区表:空闲区表的结构如下:typedef struct node int start; int length;

21、 char tag20; job; 3.算法的设计实现3.1设计实现:1.数据结构及变量说明const int maxjob=100;/定义表最大记录数 typedef struct node int start; int length; char tag20; job; job freesmaxjob;/定义空闲区表 int free_quantity; job occupysmaxjob;/定义已分配区表 int occupy_quantity;2.完成功能的主要函数initial() 初始化readdata() 从文本文件读取数据sortearliest() 最先适应算法排序earlie

22、st() 实现最先适应算法sortbest() 最佳适应算法排序bestmethod() 实现最佳适应算法sortbad() 最坏适应算法排序badmethod() 实现最坏适应算法finished() 实现主存回收view() 显示3.2.最先适应算法的功能及注释/声明变量char job_name20; int job_length; int i,j,flag,t; /输入进程名和空间大小coutjob_name; cinjob_length; flag=0; /标志变量for(i=0;i=job_length)/空闲区长度是否大于进程所需空间 flag=1; if(flag=0) /空闲

23、区长度小于进程所需空间coutendlsorry,当前没有能满足你申请长度的空闲内存,请稍候再试=job_length) t=1; i+; i-; occupysoccupy_quantity.start=freesi.start; strcpy(occupysoccupy_quantity.tag,job_name); occupysoccupy_quantity.length=job_length; occupy_quantity+; if(freesi.lengthjob_length) freesi.start+=job_length; freesi.length-=job_lengt

24、h; else for(j=i;jfree_quantity-1;j+) freesj=freesj+1; free_quantity-;最先适应算法的主要流程图如下:最先适应算法运行结果如下:3.3.最佳适应算法的实现/声明变量char job_name20; /名字 int job_length; /长度 int i,j; int max=0,min=0,maxx;/输入进程名和空间大小 coutjob_name; cinjob_length;/查找最合适的空闲区 for(i=0;ifree_quantity;i+) for(j=0;ji;j+) if(freesj.length=free

25、si.length) max=i;elsemax=j; for(j=0;j=freesi.length) min=i;elsemin=j; if(freesmin.length=job_length) maxx=i; if(freesmaxx.lengthjob_length)/ 没有能满足的空闲区 coutendlsorry,当前没有能满足你申请长度的空闲内存,请稍候再试job_length) freesmaxx.start+=job_length; freesmaxx.length-=job_length; else for(j=maxx;jfree_quantity-1;j+) free

26、sj=freesj+1;free_quantity-;最优流程图:最佳算法运行结果如下:3.4.最坏适应算法的实现/声明变量char job_name20; /名字 int job_length; /长度 int i,j; int max;/输入进程名和空间大小 coutjob_name; cinjob_length;/找出空闲区最大的 for(i=0;ifree_quantity;i+) for(j=0;ji;j+) if(freesj.lengthfreesi.length) max=i; else max=j; if(freesmax.lengthjob_length)/如果最大空闲区都

27、臂进程空间小,则不满足要求 coutendlsorry,当前没有能满足你申请长度的空闲内存,请稍候再试job_length) freesmax.start+=job_length; freesmax.length-=job_length; else for(j=max;jfree_quantity-1;j+) freesj=freesj+1; free_quantity-;最坏流程图:最坏算法运行结果如下:3.5.主存回收算法的实现/声明变量char job_name20; int i,j,flag,p=0; int start; int length; /输入要回收的进程名coutjob_n

28、ame; flag=-1; /标志变量/找到指定进程for(i=0;ioccupy_quantity;i+) if(!strcmp(occupysi.tag,job_name) flag=i; start=occupysi.start; length=occupysi.length; if(flag=-1) cout没有这个作业名endl; else /加入空闲表 for(i=0;ifree_quantity;i+) if(freesi.start+freesi.length)=start) if(i+1)free_quantity)&(freesi+1.start=start+length)

29、 freesi.length=freesi.length+freesi+1.length+length; for(j=i+1;jfree_quantity;j+) freesj=freesj+1; free_quantity-; p=1; else freesi.length+=length; p=1; if(freesi.start=(start+length) freesi.start=start; freesi.length+=length; p=1; if(p=0) freesfree_quantity.start=start; freesfree_quantity.length=le

30、ngth; free_quantity+; /删除分配表中的该作业 for(i=flag;ioccupy_quantity;i+) occupysi=occupysi+1; occupy_quantity-;主存回收的流程图如下:回收算法运行结果如下:四:模拟dos文件的建立和使用1 设计目的磁盘文件是磁盘上存储的重要信息,通过本实验模拟dos文件的建立和使用情况,理解磁盘文件的物理结构。文件管理是操作系统中重要的内容之一,不同的文件系统提供了不同的物理结构,通过实验,深入理解文件的物理结构与存取方法之间的关系,以便更好的掌握文件系统的概念。2 设计要求(1) 模拟设计dos操作系统中磁盘文件

31、的存储结构dos操作系统对磁盘文件的管理采用链接结构,将所有的链接指针集中在一起,存放在文件分配表(fat)中。连接文件的第一个物理块号登记在文件目录中。其设计思想是:假定磁盘上共有n个物理块可供使用,当要存放文件时,从fat表中寻找其值为0的项,用其对应的物理块存放文件信息,并把文件占有的各物理块用链接指针登记在fat表中,再把文件的第一个物理块号登记在文件目录中。文件目录及fat表如图所示: 在dos中fat表的前两项用来记录磁盘的类型。而从第2项开始记录磁盘的分配情况和文件各物理块的链接情况。在fat表中第三项的值如果为0,表示对应的第三块空闲。由图还知道文件a的各记录依次存放在第2、第

32、4、第15、第16、第50等六个物理块中。第50块中的指针为fff,表示文件a的结束。文件b的各记录依次存放在第7、第10、第20等三个物理块中。第20块中的指针为fff。假定磁盘存储空间共有100个物理块,设计一个文件分配表。为了简单,文件分配表可用一个数组定义,其中每一个元素与一个物理块对应。当第 i 个元素为 0 时,表示第 i 块空闲;当第 i 个元素既不为 0 也不为 fff 时,其值表示该文件的下一个物理块号。另外,再设一个空闲块总数变量记录系统还有的空闲块数。为了简单,假定一个物理块指存放一个逻辑记录,要求设计一个程序,把文件的逻辑记录结构转换成 dos 的链接结构。当用户要求将

33、已在主存的文件保存在磁盘上时,给出文件名及文件的记录个数,系统应能在磁盘上正确地保存文件。或当用户要求给指定文件增加记录时,也应正确的实现,并插在指定记录之后。为了正确地执行模拟程序,可用键盘模拟输入用户的要求。输入格式为:write(文件名,记录个数) 或insert(文件名,逻辑记录号) (2) 模拟设计便于直接存取的索引文件结构为了便于用户直接存取文件的各个逻辑记录,在 ms-dos 中通过文件目录,再沿着链查找fat表,便可直接找到指定逻辑记录对应的物理块。在小型机或更高级的文件系统中,直接存取文件的方法是为每个文件建立一个索引表,指出各逻辑记录与物理块的对应关系。最简单的形式是一个逻

34、辑记录对应一个物理块。文件目录与索引表的关系如图所示。通常索引表按照逻辑记录顺序建立,这样既有利于顺序存储,又有利于直接存储。为了标识哪些记录已经建立,哪些记录还没建立,故在索引表中增设一个标志位。写文件或插入一个记录的过程是寻找一个空闲物理块,然后将其填入索引表对应项中。其建立过程同第一题,即 write(文件名,记录号)和 insert(文件名,记录号)。要求用位示图描绘出磁盘的使用情况,并要求模拟程序执行过程的每一步都能显示文件目录、位示图、索引表。3模拟算法的实现:1.数据结构及变量名:const int fdf=-2;const int fff=-1;const int n=100;

35、/存储空间(fat表长度)int filenumber;/文件数量struct fileinfochar filename10;int startaddress;int filelength;2.实现功能的主要函数void printfmenu()/打印目录表void printffat()/打印fat表void search2()/搜索文件void write(char *tmpname,int tmplength)/写入文件void insert(char *tmpname,int insertpoint)/插入文件(1).模拟设计dos操作系统中磁盘文件的存储结构的主要算法功能及注释如下

36、:写入函数算法:void write(char *tmpname,int tmplength)int last,i,j;strcpy(filefilenumber.filename,tmpname);/复制文件名和文件块个数filefilenumber.filelength=tmplength;for(i=2;in;i+)/存文件if(fati=0) filefilenumber.startaddress=i;/首个空闲块为文件开始块last=i;fatlast=fff;break;for(i=1;itmplength;i+)/last为上个记录的位置for(j=2;jn;j+)/步进,用来确

37、定索引步长if(fatj=0)fatlast=j;last=j;fatlast=fff;break;fatlast=fff;/文件末存结束标记remainingspace-=tmplength;/改变空闲块个数filenumber+;printf(文件名和长度:%s %dn,tmpname,tmplength);写入函数的主要流程图如下:开始intlast,i,j;strcpy(filefilenumber.filename,tmpname);filefilenumber.filelength=tmplength;i=2inyfati=0yfilefilenumber.startaddress

38、=i;last=i;fatlast=fff;break;i+i=1itmplengthyj=2jnyfatlast=j;last=j;fatlast=fff;break;fatj=0yj+i+fatlast=fff;remainingspace-=tmplength;filenumber+;printf(文件名和长度:%s %dn,tmpname,tmplength);结束n写入函数运行结果如下:插入函数主要算法如下:void insert(char *tmpname,int insertpoint)int i;int last,brpoint;for(i=0;ifilenumber;i+)/

39、寻找要执行插入操作的文件,将其数组下标存入lastif(strcmp(filei.filename,tmpname)=0)/比较插入文件名与已存在文件名是否相同 last=i;break;brpoint=filelast.startaddress;/brpoint记录当前文件扫描到的位置for(i=0;iinsertpoint-1;i+)brpoint=fatbrpoint; /扫描直到找到插入位置for(i=0;in;i+)/寻找一个空闲块插入if(fati=0)fati=fatbrpoint;fatbrpoint=i;break;filelast.filelength+;/改变空闲块个数与

40、文件长度remainingspace-;printf(文件名和长度:%s %dn,tmpname,filelast.filelength);插入函数主要流程图:开始int i;int last,brpoint;i=0ifilenumberystrcmp(filei.filename,tmpname)=0ylast=i;break;i+brpoint=filelast.startaddress;i=0iinsertpoint-1brpoint=fatbrpoint;yi+i=0inyfati=0fati=fatbrpoint;fatbrpoint=i;break;yi+filelast.file

41、length+;remainingspace-;printf(文件名和长度:%s %dn,tmpname,filelast.filelength);结束nn插入的运行结果如下:(2).模拟设计便于直接存取的索引文件结构的主要算法功能及注释如下: void search(char *tmpname) int i; for(i=0;ifilenumber;i+)if(strcmp(filei.filename,tmpname)=0)/比较插入文件名与已存在文件名是否相同 printf(找到了!n); printf(文件名 起始块号 文件长度n); printf( %s %d %dn,filei.f

42、ilename,filei.startaddress,filei.filelength); void search2(int searchpoint) int i=0; int m; if(fatsearchpoint=0) printf(该点空缺,没有文件!); else if(fatsearchpoint=-1&fatsearchpoint-1=-2|fatsearchpoint=-2&fatsearchpoint+1=-1)printf(此处为系统空间!);else if(fatsearchpoint!=0) for(i=0;i=0&mfilei.filelength)printf(找到了!此处的文件名为:%s,filei.filename);break;1.模拟设计便于直接存取的索引文件结构的主要流程图如下:开始int i=0; int m;fatsearchpoint=0yprintf(该点空缺,没有文件!);fatsearchpoint=1&fatsearchpoint-1=-2|fatsearchpoint=-2&fatsearchpoint+1=-1nyprintf(此处为系统空间!);nfatsearchpoint!=0yi=0i=0&mfilei.filelengthprintf(找到了!此处的文件名为:%s,filei.filename);brea

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论