操作系统课程设计完成了
2004-06-27 22:19
471 查看
终于弄好了课程设计,不过不是自己做的
二:[/b] [/b]进程调度模拟程序[/b][/b] 设计要求:[/b][/b] 编写一程序,可以创建若干个虚拟进程,并对若干个虚拟进程进行调度,调度策略为时间片轮转。 虚拟程序的描述:[/b][/b] 虚拟指令的格式: 操作命令[/b] [/b]操作时间[/b] 其中,操作命令有以下几种: l C : 表示在CPU上计算 l I :表示输入 l O:表示输出 l W:表示等待 l H:表示进程结束 操作时间代表该操作命令要执行多长时间 假设I/O设备的数量没有限制 I、O、W三条指令实际上是不占用CPU的,执行这三条指令就应将进程放入对应的等待队列(Input等待队列、Output等待队列、Wait等待队列) 例有一虚拟程序p1.prc描述如下: c 30 o 12 c 9 i 14 h 0 该虚拟程序表示的含义是:先在CPU上计算30秒,再在输出设备上输出12秒,计算9 秒,在输入设备上输入14秒,程序结束。 实验方法:[/b][/b] 先用文本编辑器写三个虚拟程序,可以分别命名为p1.prc p2.prc p3.prc。然后编一进程调度程序,将这三个虚拟程序创建成进程,并按各虚拟进程的指令要求执行和调度。用一个文本文件, 里面只能放一个整数,表示一个时间因子,用于调节设计程序OS.EXE的执行速度。 运行结果要求:[/b][/b] [/b]要求在每个线程创建、占用处理机、开始输出、开始输入和结束操作时分别显示一行提示信息,以确定所有处理都遵守相应的进程调度规则。 要求:[/b][/b] 1. 设计的分析,解决方案 2. 进程的创建要创建进程控制块(可参考UINX的进程控制块的设计,要求有进程的必要信息) 3. 要有运行队列、就绪队列、Input等待队列、Output等待队列、Wait等待队列 4. 要有进程切换时的上下文转换过程 5. 要动态显示每个进程的当前状态及指令执行情况,动态显示每个队列的当前状态 6. 画出程序的基本结构框图和流程图 7. 对程序的每一部分要有详细的设计分析说明,说明设计实现所用的原理,采用的数据结构 8. 进程的各个操作函数的详细说明(如创建进程,销毁进程等) 9. 源代码格式规范,注释不少于三分之一 10. 对运行的结果要有结果的分析, 11. 设计中遇到的问题,设计的心得体会 12. 参考资料 13. 开发工具不限 系统流程图: 1.3 个作业 2. 按照时间片轮转法实现进程调度 3.五个公用队列
C 时间片到 等待结束 C
I H
O
W
源程序 #define NULL 0 #include <stdio.h> #include <string.h> #include <malloc.h> #include <time.h> //定义一个pcb的结构体 FILE *GroupFile[10]; typedef struct index{ char name; //指令 int time; //指令执行时间 }index; struct pcb { char filename[10]; //进程名 int id; //作业编号 int exetoIndex; //当前正在执行指令 char status; //当前状态 int wtime; //等待时间 }; struct pcb jobpcb[100]; //pcb表 typedef struct job{ index idx[100]; //指令集 int pcbnum; //pcb编号 对应 }job; job jobtab[100]; //作业表 char jobp[3][50]; //作业 //队列 struct Qnode { int pcbnum[100]; //pcb编号 int head,tail; }; struct Qnode Queue[5]; //5个队列 0E 1R 2I 3O 4W void initqueue(struct Qnode *l); //延迟 void delay( ){ long begin,end; time(&begin); do { time(&end); } while((end-begin)<=1); } //字符转化为数值 int change(char *m){ int i,j=0; int len=strlen(m); for(i=0;i<len;i++) j=j*10+m[i]-'0'; return j; } //申请 pcb int AllocPCB(){ int i; for(i=0;i<3;i++) if(jobpcb[i].id ==-1) break; if(i<3) return i; return -1; } //申请job int AllocJob(){ int i; for(i=0;i<3;i++) if(jobtab[i].pcbnum == -1) break; if(i<3) return i; return -1; } //显示指令 void displayIndex(){ int i,j; for(i=0;i<3;i++){ printf(" Job % d /n",i+1); for(j=0;j<10;j++) printf(" %d %c % d /n",j+1, jobtab[i].idx[j].name,jobtab[i].idx[j].time); } } //创建进程程序 int creatpcbline(){ char line[10]; int i,ll,jnum, pnum, ln=0, bpos, pos=0; char buff[50]; char name [20]; char ch; for(i=0;i<3;i++){ ln=0; jnum=AllocJob(); if(jnum == -1) return 0; pnum=AllocPCB(); if(pnum == -1) return 0; jobtab[jnum].pcbnum=pnum; strcpy(jobpcb[pnum].filename," "); jobpcb[pnum].status='r'; jobpcb[pnum].exetoIndex=0; jobpcb[pnum].id=jnum; jobpcb[pnum].wtime=0; int ln=strlen(jobp[i]); pos=0; while(pos<len){ while(jobp[i][pos]==' ') pos++; jobtab[jnum].idx[ln].name=jobp[i][pos++];/// while(jobp[i][pos]==' ') pos++; bpos=0; while(jobp[i][pos]!=' ') buff[bpos++]=jobp[i][pos++]; buff[bpos]='/0'; jobtab[jnum].idx[ln].time=change(buff);///// if(pos<len) {pos++;ln++; } } } displayIndex(); } /*初始化队列 void initqueue(struct Qnode *l){ l->head=0; l->tail=0; } //插进入队列/ void insertqueue(struct Qnode *l,int pcbnum){ l->pcbnum[l->tail++]=pcbnum; } //队列是否为空 int EmptyQueue( struct Qnode l){ if(l.head==l.tail) return 1; return 0; } //删除队列 void outqueue(struct Qnode *l,int *pcbnum) { if (l->head>=l->tail ) *pcbnum=-1; else *pcbnum=l->pcbnum[l->head++]; } //显示作业 void display(){ int i,j; for(i=0;i<5;i++){ printf(" 队列 %d ",i); for(j=Queue[i].head;j<Queue[i].tail;j++) printf("pcb 编号 %d /n/n ",Queue[i].pcbnum[j]); } } //作业入队列 void JobEnQueueInit( int * total){ int i,num ,Index=0; char cmd; for( i=0;i<3;i++){ if(jobpcb[i].id>=0){ cmd=jobtab[ jobpcb[i].id ].idx[ Index ].name; switch(cmd){ case 'c': insertqueue(&Queue[1],i); jobpcb[i].status='r'; break; case 'i': insertqueue(& Queue[2],i);jobpcb[i].status='i'; break; case 'o': insertqueue(& Queue[3],i);jobpcb[i].status='o'; break; case 'w': insertqueue(& Queue[4],i);jobpcb[i].status='w'; break; case 'h': jobpcb[i].status='h'; num=jobpcb[i].id;jobtab[num].pcbnum=-1;jobpcb[i].id=-1; } if(cmd== 'h') {jobpcb[i].wtime=0; total--;} jobpcb[i].wtime=jobtab [ jobpcb[i].id ].idx[Index].time; (*total)++; } } } void save (){ FILE *fp; int i; fp=fopen("pcbtable.txt","a"); fprintf(fp," 文件名 作业编号 执行到指令数 所处状态 等待时间 /n" ); for(i=0;i<3;i++) fprintf(fp," /t %s /t %d /t %d /t %c /t %d /n" , jobpcb[i].filename,jobpcb[i].id,jobpcb[i].exetoIndex, jobpcb[i].status,jobpcb[i].wtime ); fclose(fp); } //作业入队列 void JobEnQueue( int pcbnum,int Index ,int *total){ int num; char cmd; if(jobpcb[pcbnum].id>=0){ cmd=jobtab[ jobpcb[pcbnum].id ].idx[ Index ].name; switch(cmd){ case 'c': insertqueue(&Queue[1],pcbnum); jobpcb[pcbnum].status='r'; break; case 'i': insertqueue(& Queue[2],pcbnum);jobpcb[pcbnum].status='i'; break; case 'o': insertqueue(& Queue[3],pcbnum);jobpcb[pcbnum].status='o'; break; case 'w': insertqueue(& Queue[4],pcbnum);jobpcb[pcbnum].status='w'; break; case 'h': jobpcb[pcbnum].status='h'; num=jobpcb[pcbnum].id;jobtab[num].pcbnum=-1;jobpcb[pcbnum].id=-1; } if(cmd== 'h') { jobpcb[pcbnum].wtime=0; printf(" /n/t/t作业 %d 完成/n", pcbnum+1, jobpcb[ pcbnum].status); (*total)--; } else jobpcb[pcbnum].wtime=jobtab [ jobpcb[pcbnum].id ].idx[Index].time; printf(" /n/t/t作业 %d /n ", pcbnum+1); printf("/t/t/t/t所处状态 : %c /n",jobpcb[ pcbnum].status); printf("/t/t还需要时间 %d 秒/n",jobpcb[ pcbnum].wtime); } } //得到队列的首元素 int GetHead(struct Qnode l){ return l.pcbnum[l.head]; } //执行 void run (){ int i, flag=0, time=10, pcbnum, Index=0, exenum, num, quenum; char cmd; int j,m,n; int total=0; JobEnQueueInit( &total ); save(); while( total!=0 ){ if( !EmptyQueue( Queue[1]) ){ outqueue(&Queue[1],&pcbnum); insertqueue(&Queue[0], pcbnum); else pcbnum=GetHead(Queue[0]); delay(); jobpcb[ pcbnum].status='e'; printf(" /n/t/t作业 %d /n",pcbnum+1); printf(" /t/t/t所处状态: %c /t执行了 %d 秒/n", jobpcb[ pcbnum].status, time); for(i=0;i<3;i++){ if(jobpcb[i].id>=0){ //所有的作业除在就绪队列获执行结束的外等待时间 都间时间片 if( jobpcb[i].status!='r'&&jobpcb[i].status!='h') jobpcb[i].wtime=jobpcb[i].wtime-time; if(jobpcb[i].wtime<=0){ //查找所有的队列 所在位置 for(j=0;j<5;j++){ for(m=Queue[j].head;m<Queue[j].tail;m++){ if(Queue[j].pcbnum[m]==i) {flag=1;break; } } if(flag==1) break; } if(flag==1){ //删除该指令 for(n=m;n<Queue[j].tail;n++) Queue[j].pcbnum
=Queue[j].pcbnum[n+1]; Queue[j].tail--; jobpcb[i].exetoIndex++; Index=jobpcb[i].exetoIndex; JobEnQueue( i,Index,&total ); } } } } if(!EmptyQueue( Queue[1]) ){ outqueue(&Queue[0],&pcbnum); if(jobpcb[pcbnum].wtime>0){ insertqueue(&Queue[1], pcbnum); jobpcb[pcbnum].status='r'; } } printf(" /n/n/t/t 还有/t %d 个作业没有完成 /n",total ); save(); } } //初始化 void InitFile(){ int i; strcpy (jobp[0]," c 20 i 20 o 15 h 0 ");////////////////////////改 strcpy (jobp[1]," i 10 c 20 c 10 h 0 "); strcpy (jobp[2]," c 30 i 20 c 5 h 0 "); for(i=0;i<100;i++){ jobpcb[i].exetoIndex=0; strcpy(jobpcb[i].filename," "); jobpcb[i].id=-1; jobpcb[i].status='r'; jobpcb[i].wtime=0; } for(i=0;i<100;i++) jobtab[i].pcbnum=-1; for(i=0;i<5;i++) initqueue(&Queue[i]); //GroupFile[0]=fopen("1.txt","r"); //GroupFile[1]=fopen("2.txt","r"); //GroupFile[2]=fopen("3.txt","r"); } void main(){ InitFile(); creatpcbline(); run (); } 设计说明 : 这个程序分了三部分,初始化,创建进程,运行进程,我们三个人分开做,我主要做创建进程的一个函数 即主函数中的 creatpcbline(); 设计心得: 操作系统是计算机系统中必不可少的系统软件。它是计算机系统中各种资源的管理者和各种活动的组织者、指挥者。操作系统采用时间片法调度进程,使系统资源得到充分的利用,用户也可以花更少的时间完成更多的工作,这次模拟系统调度进程,让我明白了系统时间片的调度方法,对操作系统理论的学习更加深一层.
二:[/b] [/b]进程调度模拟程序[/b][/b] 设计要求:[/b][/b] 编写一程序,可以创建若干个虚拟进程,并对若干个虚拟进程进行调度,调度策略为时间片轮转。 虚拟程序的描述:[/b][/b] 虚拟指令的格式: 操作命令[/b] [/b]操作时间[/b] 其中,操作命令有以下几种: l C : 表示在CPU上计算 l I :表示输入 l O:表示输出 l W:表示等待 l H:表示进程结束 操作时间代表该操作命令要执行多长时间 假设I/O设备的数量没有限制 I、O、W三条指令实际上是不占用CPU的,执行这三条指令就应将进程放入对应的等待队列(Input等待队列、Output等待队列、Wait等待队列) 例有一虚拟程序p1.prc描述如下: c 30 o 12 c 9 i 14 h 0 该虚拟程序表示的含义是:先在CPU上计算30秒,再在输出设备上输出12秒,计算9 秒,在输入设备上输入14秒,程序结束。 实验方法:[/b][/b] 先用文本编辑器写三个虚拟程序,可以分别命名为p1.prc p2.prc p3.prc。然后编一进程调度程序,将这三个虚拟程序创建成进程,并按各虚拟进程的指令要求执行和调度。用一个文本文件, 里面只能放一个整数,表示一个时间因子,用于调节设计程序OS.EXE的执行速度。 运行结果要求:[/b][/b] [/b]要求在每个线程创建、占用处理机、开始输出、开始输入和结束操作时分别显示一行提示信息,以确定所有处理都遵守相应的进程调度规则。 要求:[/b][/b] 1. 设计的分析,解决方案 2. 进程的创建要创建进程控制块(可参考UINX的进程控制块的设计,要求有进程的必要信息) 3. 要有运行队列、就绪队列、Input等待队列、Output等待队列、Wait等待队列 4. 要有进程切换时的上下文转换过程 5. 要动态显示每个进程的当前状态及指令执行情况,动态显示每个队列的当前状态 6. 画出程序的基本结构框图和流程图 7. 对程序的每一部分要有详细的设计分析说明,说明设计实现所用的原理,采用的数据结构 8. 进程的各个操作函数的详细说明(如创建进程,销毁进程等) 9. 源代码格式规范,注释不少于三分之一 10. 对运行的结果要有结果的分析, 11. 设计中遇到的问题,设计的心得体会 12. 参考资料 13. 开发工具不限 系统流程图: 1.3 个作业 2. 按照时间片轮转法实现进程调度 3.五个公用队列
执行队列 |
时间片 |
就绪等待队列 |
CPU |
输入等待队列 |
结束 |
输出等待队列 |
阻塞等待队列 |
源程序 #define NULL 0 #include <stdio.h> #include <string.h> #include <malloc.h> #include <time.h> //定义一个pcb的结构体 FILE *GroupFile[10]; typedef struct index{ char name; //指令 int time; //指令执行时间 }index; struct pcb { char filename[10]; //进程名 int id; //作业编号 int exetoIndex; //当前正在执行指令 char status; //当前状态 int wtime; //等待时间 }; struct pcb jobpcb[100]; //pcb表 typedef struct job{ index idx[100]; //指令集 int pcbnum; //pcb编号 对应 }job; job jobtab[100]; //作业表 char jobp[3][50]; //作业 //队列 struct Qnode { int pcbnum[100]; //pcb编号 int head,tail; }; struct Qnode Queue[5]; //5个队列 0E 1R 2I 3O 4W void initqueue(struct Qnode *l); //延迟 void delay( ){ long begin,end; time(&begin); do { time(&end); } while((end-begin)<=1); } //字符转化为数值 int change(char *m){ int i,j=0; int len=strlen(m); for(i=0;i<len;i++) j=j*10+m[i]-'0'; return j; } //申请 pcb int AllocPCB(){ int i; for(i=0;i<3;i++) if(jobpcb[i].id ==-1) break; if(i<3) return i; return -1; } //申请job int AllocJob(){ int i; for(i=0;i<3;i++) if(jobtab[i].pcbnum == -1) break; if(i<3) return i; return -1; } //显示指令 void displayIndex(){ int i,j; for(i=0;i<3;i++){ printf(" Job % d /n",i+1); for(j=0;j<10;j++) printf(" %d %c % d /n",j+1, jobtab[i].idx[j].name,jobtab[i].idx[j].time); } } //创建进程程序 int creatpcbline(){ char line[10]; int i,ll,jnum, pnum, ln=0, bpos, pos=0; char buff[50]; char name [20]; char ch; for(i=0;i<3;i++){ ln=0; jnum=AllocJob(); if(jnum == -1) return 0; pnum=AllocPCB(); if(pnum == -1) return 0; jobtab[jnum].pcbnum=pnum; strcpy(jobpcb[pnum].filename," "); jobpcb[pnum].status='r'; jobpcb[pnum].exetoIndex=0; jobpcb[pnum].id=jnum; jobpcb[pnum].wtime=0; int ln=strlen(jobp[i]); pos=0; while(pos<len){ while(jobp[i][pos]==' ') pos++; jobtab[jnum].idx[ln].name=jobp[i][pos++];/// while(jobp[i][pos]==' ') pos++; bpos=0; while(jobp[i][pos]!=' ') buff[bpos++]=jobp[i][pos++]; buff[bpos]='/0'; jobtab[jnum].idx[ln].time=change(buff);///// if(pos<len) {pos++;ln++; } } } displayIndex(); } /*初始化队列 void initqueue(struct Qnode *l){ l->head=0; l->tail=0; } //插进入队列/ void insertqueue(struct Qnode *l,int pcbnum){ l->pcbnum[l->tail++]=pcbnum; } //队列是否为空 int EmptyQueue( struct Qnode l){ if(l.head==l.tail) return 1; return 0; } //删除队列 void outqueue(struct Qnode *l,int *pcbnum) { if (l->head>=l->tail ) *pcbnum=-1; else *pcbnum=l->pcbnum[l->head++]; } //显示作业 void display(){ int i,j; for(i=0;i<5;i++){ printf(" 队列 %d ",i); for(j=Queue[i].head;j<Queue[i].tail;j++) printf("pcb 编号 %d /n/n ",Queue[i].pcbnum[j]); } } //作业入队列 void JobEnQueueInit( int * total){ int i,num ,Index=0; char cmd; for( i=0;i<3;i++){ if(jobpcb[i].id>=0){ cmd=jobtab[ jobpcb[i].id ].idx[ Index ].name; switch(cmd){ case 'c': insertqueue(&Queue[1],i); jobpcb[i].status='r'; break; case 'i': insertqueue(& Queue[2],i);jobpcb[i].status='i'; break; case 'o': insertqueue(& Queue[3],i);jobpcb[i].status='o'; break; case 'w': insertqueue(& Queue[4],i);jobpcb[i].status='w'; break; case 'h': jobpcb[i].status='h'; num=jobpcb[i].id;jobtab[num].pcbnum=-1;jobpcb[i].id=-1; } if(cmd== 'h') {jobpcb[i].wtime=0; total--;} jobpcb[i].wtime=jobtab [ jobpcb[i].id ].idx[Index].time; (*total)++; } } } void save (){ FILE *fp; int i; fp=fopen("pcbtable.txt","a"); fprintf(fp," 文件名 作业编号 执行到指令数 所处状态 等待时间 /n" ); for(i=0;i<3;i++) fprintf(fp," /t %s /t %d /t %d /t %c /t %d /n" , jobpcb[i].filename,jobpcb[i].id,jobpcb[i].exetoIndex, jobpcb[i].status,jobpcb[i].wtime ); fclose(fp); } //作业入队列 void JobEnQueue( int pcbnum,int Index ,int *total){ int num; char cmd; if(jobpcb[pcbnum].id>=0){ cmd=jobtab[ jobpcb[pcbnum].id ].idx[ Index ].name; switch(cmd){ case 'c': insertqueue(&Queue[1],pcbnum); jobpcb[pcbnum].status='r'; break; case 'i': insertqueue(& Queue[2],pcbnum);jobpcb[pcbnum].status='i'; break; case 'o': insertqueue(& Queue[3],pcbnum);jobpcb[pcbnum].status='o'; break; case 'w': insertqueue(& Queue[4],pcbnum);jobpcb[pcbnum].status='w'; break; case 'h': jobpcb[pcbnum].status='h'; num=jobpcb[pcbnum].id;jobtab[num].pcbnum=-1;jobpcb[pcbnum].id=-1; } if(cmd== 'h') { jobpcb[pcbnum].wtime=0; printf(" /n/t/t作业 %d 完成/n", pcbnum+1, jobpcb[ pcbnum].status); (*total)--; } else jobpcb[pcbnum].wtime=jobtab [ jobpcb[pcbnum].id ].idx[Index].time; printf(" /n/t/t作业 %d /n ", pcbnum+1); printf("/t/t/t/t所处状态 : %c /n",jobpcb[ pcbnum].status); printf("/t/t还需要时间 %d 秒/n",jobpcb[ pcbnum].wtime); } } //得到队列的首元素 int GetHead(struct Qnode l){ return l.pcbnum[l.head]; } //执行 void run (){ int i, flag=0, time=10, pcbnum, Index=0, exenum, num, quenum; char cmd; int j,m,n; int total=0; JobEnQueueInit( &total ); save(); while( total!=0 ){ if( !EmptyQueue( Queue[1]) ){ outqueue(&Queue[1],&pcbnum); insertqueue(&Queue[0], pcbnum); else pcbnum=GetHead(Queue[0]); delay(); jobpcb[ pcbnum].status='e'; printf(" /n/t/t作业 %d /n",pcbnum+1); printf(" /t/t/t所处状态: %c /t执行了 %d 秒/n", jobpcb[ pcbnum].status, time); for(i=0;i<3;i++){ if(jobpcb[i].id>=0){ //所有的作业除在就绪队列获执行结束的外等待时间 都间时间片 if( jobpcb[i].status!='r'&&jobpcb[i].status!='h') jobpcb[i].wtime=jobpcb[i].wtime-time; if(jobpcb[i].wtime<=0){ //查找所有的队列 所在位置 for(j=0;j<5;j++){ for(m=Queue[j].head;m<Queue[j].tail;m++){ if(Queue[j].pcbnum[m]==i) {flag=1;break; } } if(flag==1) break; } if(flag==1){ //删除该指令 for(n=m;n<Queue[j].tail;n++) Queue[j].pcbnum
=Queue[j].pcbnum[n+1]; Queue[j].tail--; jobpcb[i].exetoIndex++; Index=jobpcb[i].exetoIndex; JobEnQueue( i,Index,&total ); } } } } if(!EmptyQueue( Queue[1]) ){ outqueue(&Queue[0],&pcbnum); if(jobpcb[pcbnum].wtime>0){ insertqueue(&Queue[1], pcbnum); jobpcb[pcbnum].status='r'; } } printf(" /n/n/t/t 还有/t %d 个作业没有完成 /n",total ); save(); } } //初始化 void InitFile(){ int i; strcpy (jobp[0]," c 20 i 20 o 15 h 0 ");////////////////////////改 strcpy (jobp[1]," i 10 c 20 c 10 h 0 "); strcpy (jobp[2]," c 30 i 20 c 5 h 0 "); for(i=0;i<100;i++){ jobpcb[i].exetoIndex=0; strcpy(jobpcb[i].filename," "); jobpcb[i].id=-1; jobpcb[i].status='r'; jobpcb[i].wtime=0; } for(i=0;i<100;i++) jobtab[i].pcbnum=-1; for(i=0;i<5;i++) initqueue(&Queue[i]); //GroupFile[0]=fopen("1.txt","r"); //GroupFile[1]=fopen("2.txt","r"); //GroupFile[2]=fopen("3.txt","r"); } void main(){ InitFile(); creatpcbline(); run (); } 设计说明 : 这个程序分了三部分,初始化,创建进程,运行进程,我们三个人分开做,我主要做创建进程的一个函数 即主函数中的 creatpcbline(); 设计心得: 操作系统是计算机系统中必不可少的系统软件。它是计算机系统中各种资源的管理者和各种活动的组织者、指挥者。操作系统采用时间片法调度进程,使系统资源得到充分的利用,用户也可以花更少的时间完成更多的工作,这次模拟系统调度进程,让我明白了系统时间片的调度方法,对操作系统理论的学习更加深一层.
相关文章推荐
- 使用netbeans完成的操作系统课程设计----存储管理模拟
- 使用netbeans完成的操作系统课程设计-设备管理模拟
- 操作系统课程设计-线程和进程的同步与互斥
- 操作系统课程设计-二级文件系统,Windows平台版本,c语言
- 操作系统课程设计--银行家算法的模拟实现
- 操作系统课程设计之二级文件系统演示
- 操作系统课程设计和实验
- 操作系统课程设计
- 操作系统的课程设计《进程管理》
- 大一的第一篇的C语言课程设计完成了,链表的选择排序
- 网校搭建完成,课程还需要设计吗?
- 操作系统课程设计 基于DOS的多任务系统的实现
- 操作系统课程设计nachos 4、5、6、7、8
- 操作系统课程设计 -nachos- lab-new1
- 学习<<汇编语言 -王爽>>,自已完成的一道课程设计题 (5)
- 操作系统课程设计(一)
- 操作系统存储管理实验课程设计报告
- 操作系统课程设计代码
- 操作系统课程设计
- 操作系统课程设计 消息缓冲队列通信