当前位置:文档之家› 43316341操作系统课程设计指导书113301-113302

43316341操作系统课程设计指导书113301-113302

43316341操作系统课程设计指导书113301-113302
43316341操作系统课程设计指导书113301-113302

设计题目1 进程调度算法

1.1 设计目的

进程管理是操作系统中的重要功能,用来创建进程、撤消进程、实现进程状态转换,它提供了在可运行的进程之间复用CPU的方法。在进程管理中,进程调度是核心,因为在采用多道程序设计的系统中,往往有若干个进程同时处于就绪状态,当就绪进程个数大于处理器数目时,就必须依照某种策略决定哪些进程优先占用处理器。本实验模拟在单处理器情况下的进程调度,目的是加深对进程调度工作的理解,掌握不同调度算法的优缺点。

下面回顾一下进程管理的相关内容。

1.1.1 进程控制块

为了管理和控制进程,系统在创建每一个进程时,都为其开辟一个专用的存储区,用以随时记录它在系统中的动态特性。而当一个进程被撤消时,系统就收回分配给它的存储区。通常,把这一存储区称为该进程的“进程控制块”(Process Control Block)。

由于PCB是随着进程的创建而建立,随着进程的撤消而取消的,因此系统是通过PCB 来“感知”一个个进程的,PCB是进程存在的唯一标志。

随操作系统的不同,PCB的格式、大小以及内容也不尽相同。一般地,在PCB中大致应包括如下4方面的信息。

·标识信息:进程名等。

·说明信息:进程状态、程序存放位置、数据存放位置等。

·现场信息:通用寄存器内容、控制寄存器内容、断点地址等。

·管理信息:进程优先数、队列指针等。

1.1.2 进程控制块队列

在多道程序设计环境里,同时会创建多个进程。当计算机系统只有一个CPU时,每次只能让一个进程运行,其他的进程或处于就绪状态,或处于阻塞状态。为了对这些进程进行管理,操作系统要做三件事。

(1)把处于相同状态的进程的PCB,通过各自的队列指针链接在一起,形成一个个队列。通常有运行队列、就绪队列、阻塞队列。

(2)为每一个队列设立一个队列头指针,它总是指向排在队列之首的进程的PCB。

(3)排在队尾的进程的PCB,它的“队列指针”项内容应该为“NULL”,或一个特殊的符号,以表示这是该队的队尾PCB。

在单CPU系统中,任何时刻都只有一个进程处于运行状态,因此运行队列中只能有一个PCB;系统中所有处于就绪状态的进程的PCB排成一队,称其为“就绪队列”。一般地,就绪队列中会有多个进程的PCB排在里面,它们形成处理机分配的候选对象。如果就绪队列里没有PCB存在,则称该队列为空;所有处于阻塞状态进程的PCB,应该根据阻塞的原因进行排队,每一个都称为一个“阻塞队列”。比如等待磁盘输入/输出进程的PCB排成一个队列,等待打印机输出进程的PCB排成一个队列等。所以,系统中可以有多个阻塞队列,每个阻塞队列中可以有多个进程的PCB,也可以为空。

1.1.3 进程调度算法

进程调度算法用于确定就绪队列中的哪一个进程即将获得CPU。常用的进程调度算法有先来先服务法、时间片轮转法、优先数法等。

1.先来先服务调度算法

先来先服务调度算法的基本思想是:以到达就绪队列的先后次序为标准来选择占用处理机的进程。一个进程一旦占有处理机,就一直使用下去,直至正常结束或因等待某事件的发生而让出处理机。采用这种算法时,应该这样来管理就绪队列:到达的进程的PCB总是排在就绪队列末尾;调度程序总是把CPU分配给就绪队列中的第一个进程使用。

2.时间片轮转法

时间片轮转调度算法的基本思想是:为就绪队列中的每一个进程分配一个称为“时间片”的时间段,它是允许该进程运行的时间长度。在使用完一个时间片后,即使进程还没有运行完毕,也要强迫其释放处理机,让给另一个进程使用。它自己则返回到就绪队列末尾,排队等待下一次调度的到来。采用这种调度算法时,对就绪队列的管理与先来先服务完全相同。主要区别是进程每次占用处理机的时间由时间片决定,而不是只要占用处理机就一直运行下去,直到运行完毕或为等待某一事件的发生而自动放弃。

3.优先数调度算法

优先数调度算法的基本思想是:为每一个进程确定一个优先数,进程就绪队列按照优先数排序。

如何确定进程的优先数(也就是进程的优先级)?可以从如下几个方面考虑。

(1)根据进程的类型。系统中既有系统进程,又有用户进程。系统进程完成的任务是提供系统服务,分配系统资源,因此,给予系统进程较高的优先数能够提高系统的工作效率。

(2)根据进程执行任务的重要性。重要性和紧迫性高的进程应当被赋予较高的优先级。

(3)根据进程程序的性质。一个CPU繁忙的进程,由于需要占用较长的运行时间,影响系统整体效率的发挥,因此只能给予较低的优先数。一个I/O繁忙的进程,给予它较高的优先数后,就能充分发挥CPU和外部设备之间的并行工作能力。

(4)根据对资源的要求。系统资源有处理机、内存储器和外部设备等。可以按照一个进程所需资源的类型和数量,确定它的优先数。比如给予占用CPU时间短或内存容量少的进程以较高的优先数,这样可以提高系统的吞吐量。

(5)根据用户的请求。系统可以根据用户的请求,给予它的进程很高的优先数,作“加急”处理。

4.多级队列调度算法

多级队列调度算法也称多级反馈队列调度算法,它是时间片调度算法与优先数调度算法的结合。实行这种调度算法时,系统中将维持多个就绪队列,每个就绪队列具有不同的调度级别,可以获得不同长度的时间片。例如,系统维持N个就绪队列,第1级就绪队列中进程的调度级别最高,可获得的时间片最短,第N级就绪队列中进程的调度级别最低,可获得的时间片最长。

具体的调度方法是:创建一个新进程时,它的PCB将进入第1级就绪队列的末尾。对于在第1级到第N-1级队列中的进程,如果在分配给它的时间片内完成了全部工作,那么就撤离系统;如果在时间片没有用完时提出了输入/输出请求或要等待某事件发生,那么就

进入相应的阻塞队列里等待。在所等待的事件出现时,仍回到原队列末尾,参与下一轮调度(也就是每个队列实行先来先服务调度算法);如果用完了时间片还没有完成自己的工作,那么只能放弃对CPU的使用,降到低一级队列的末尾,参与那个队列的调度。对位于最后一个队列里的进程,实行时间片轮转调度算法。

整个系统最先调度1级就绪队列;只有在上一级就绪队列为空时,才去下一级队列调度。当比运行进程更高级别的队列中到达一个进程(可以肯定,在此之前比运行进程级别高的所有队列全为空)时,系统将立即停止当前运行进程的运行,让它回到自己队列的末尾,转去运行级别高的那个进程。

可以看出,多级队列调度算法优先照顾I/O繁忙的进程。I/O繁忙的进程在获得一点CPU 时间后就会提出输入/输出请求,因此它们总是被保持在1、2级等较前面的队列中,总能获得较多的调度机会。对于CPU繁忙的进程,它们需要较长的CPU时间,因此会逐渐地由级别高的队列往下降,以获得更多的CPU时间,它们“沉”得越深,被调度到的机会就越少。但是,一旦被调度到,就会获得更多的CPU时间。

1.2 设计要求

1.2.1 界面要求

实验要求采用简单的控制台界面,包括一级功能菜单,如图1-1所示。

图1-1 界面要求

1.2.2功能要求

实验应该包括以下功能:

1.运行先来先服务进程调度算法;

2.运行时间片轮转进程调度算法;

3.运行优先数进程调度算法;

4.运行多级反馈队列进程调度算法;

5.显示就绪进程队列;

6.显示运行进程队列;

7.显示阻塞进程队列;

8.创建新进程;

9.阻塞进程;

10.唤醒进程;

11.删除进程;

12.退出程序。

1.3 设计步骤

1.3.1 总体设计

确定程序包含多少个模块,每个模块有哪些功能、包括哪些函数,模块之间的调用关系如何。由于本实验并不复杂,所以只用一个模块实现。要求宏、数据结构、全局变量和函数原型放在头文件中,而函数实现放在源文件中。假设头文件名为process_schedule.h,源程序文件名为process_schedule.cpp。实验中用到的主要数据结构是进程控制块,其结构如图1-2所示。实验中用到1个宏和8个全局变量,如图1-3所示。实验中用到的主要函数有10个,如图1-4所示。

图1-2 进程控制块

图1-3 宏和全局变量

图1-4 函数名称及作用

1.3.2 详细设计及实现

1. 头文件

头文件中含有图1-2、图1-3和图1-4的内容。

#include

#include

#include

#include

#include

#define MAX_PROCESS 10

int process_number=0; //下一个可用的进程编号

typedef struct pcb{

struct pcb *next; //下一个进程控制块指针

char process_name[20]; //进程名

int process_number; //进程编号

int process_start_moment; //进程启动时刻

int process_need_time; //要求运行时间

int process_time_slice; //时间片

int process_priority; //优先数

}PCB; //自定义数据类型:进程控制块

PCB pcb_table[MAX_PROCESS]; //进程控制块表

PCB *pcb_run=NULL; //进程运行队列头指针

PCB *pcb_free=NULL; //进程空闲队列头指针

PCB *pcb_ready=NULL; //进程就绪队列头指针

PCB *pcb_ready_rear=NULL; //进程就绪队列尾指针

PCB *pcb_blocked=NULL; //阻塞队列头指针

PCB *pcb_blocked_rear=NULL; //阻塞队列尾指针

void init_pcb_table( ); //初始化进程控制块表

void print_space(int num); //显示若干个空格

void display_process_queue(PCB *queue); //显示进程队列

PCB *create_process( ); //创建进程函数,成功时返回新创建进程的PCB,失败时返回NULL。

void block_process_by_name( ); //阻塞指定名称的进程。

void wakeup_process( ); //唤醒进程

void FCFS( ); //先来先服务进程调度算法

void RR( ); //时间片轮转进程调度算法

void HPF( ); //优先数进程调度算法

void MFBQ( ); //多级反馈队列进程调度算法

2. 主函数main

主函数用来初始化进程队列,显示菜单,接收用户输入的菜单选项,并根据用户的选项执行相应的功能。其处理流程如下:

main( ){

初始化进程控制块表;

while(1){

显示菜单;

输出提示信息;

接收用户输入的选项,如果输入不是数字1~8或者字母a~d则重新输入;

switch(选项){

case …1?:

调用先来先服务进程调度算法;

break;

case …2?:

调用时间片轮转进程调度算法;

break;

case …3?:

调用优先数进程调度算法;

break;

case …4?:

调用多级反馈队列进程调度算法;

break;

case …5?:

显示就绪进程队列;

break;

case …6?:

显示阻塞进程队列;

break;

case …7?:

显示运行进程队列;

break;

case …a?:

调用创建进程函数;

break;

case …b?:

调用删除进程函数;

break;

case …c?:

调用阻塞进程函数;

break;

case …d?:

调用唤醒进程函数;

break;

case …8?:

返回;

}

}

返回;

}

说明:通常用循环语句和多分支语句实现菜单。while语句实现菜单的循环选择,switch 语句实现功能分支,只有当用户输入数字8时,才会跳出循环,结束程序的执行,输入其它

合法数字或者字符时,程序将执行对应的功能,并在执行完功能后,重新显示菜单,供用户做下一步选择。

main函数的源代码如下:

#include "process_schedule.h" //包含头文件

int main(int argc,char *argv[ ]){

char select; //存放用户选择的菜单项

init_pcb_table( ); //初始化进程控制块表

while(1){

printf("|----------MAIN MENU-------------|\n"); //显示菜单项

printf("| 1:first come first served |\n");

printf("| 2:round robin |\n");

printf("| 3:highest priority first |\n");

printf("| 4:multi_level feedback queue |\n");

printf("| 5:display ready process queue |\n");

printf("| 6:display blocked process queue |\n");

printf("| 7:display running queue |\n");

printf("| a:create a process |\n");

printf("| b:delete a process |\n");

printf("| c:block a process |\n");

printf("| d:wakeup a process |\n");

printf("| 8:exit |\n");

printf("|-----------------------------------|\n");

printf("select a function(1~8,a~d):"); //输出提示信息

do{

select=(char)getch( ); //接收用户的选项}while(!((49<=select&&select<=56)||(97<=select&&select<=100)));

system("cls"); //清屏

switch(select){ //由选项控制程序功能

case '1':

FCFS( );

break;

case '2':

RR( );

break;

case '3':

HPF( );

break;

case '4':

MFBQ( );

break;

case '5':

printf(" ready queue\n");

display_process_queue(pcb_ready);

break;

case '6':

printf(" blocked queue\n");

display_process_queue(pcb_blocked);

break;

case '7':

printf(" running queue\n");

display_process_queue(pcb_run);

break;

case 'a':

create_process( );

break;

case 'b':

break;

case 'c':

block_process_by_name( );

break;

case 'd':

wakeup_process( );

break;

case '8':

return 0;

}

printf("\nPress any key to return to main menu.");

getch( );

system("cls");

}

return 0;

}

有了头文件和主函数就可以编译、链接并运行程序,测试程序的主菜单是否正常工作。现在运行程序,可以看到程序仅仅显示一个主菜单,如果你选择1~7和a~e项对应的功能,该程序不会有所反应,因为你还没有编写相关的功能函数。如果你选择8,则程序终止执行。这说明主菜单能正常工作。此后,你可以每实现一个函数就测试程序是否正确,如果不正确则修改这个函数,直到它正确为止;如果正确,则实现下一个函数。如此每次实现一个函数,直到所有函数都正确实现,直到整个程序能正确执行。

3. 进程控制块表的初始化函数init_pcb_table( )

该函数用来给进程控制块表即数组pct_table赋初值,并且将数组元素从头到尾串成链表,形成进程空闲队列。每个数组元素的初值为:进程名为空字符串,进程启动时刻为0,要求运行时间为0,时间片为0,优先数为0。初始化完成后的进程控制块表如图1-5所示。

void init_pcb_table( )

{

int i=0;

pcb_free=&pcb_table[0];

pcb_table[MAX_PROCESS-1].next=NULL;

pcb_table[MAX_PROCESS-1].process_number=0;

pcb_table[MAX_PROCESS-1].process_start_moment=0;

pcb_table[MAX_PROCESS-1].process_need_time=0;

pcb_table[MAX_PROCESS-1].process_time_slice=0;

pcb_table[MAX_PROCESS-1].process_priority=0;

strcpy(pcb_table[MAX_PROCESS-1].process_name,"");

for(i=0;i

pcb_table[i].next=&pcb_table[i+1];

pcb_table[i].process_number=0;

pcb_table[i].process_start_moment=0;

pcb_table[i].process_need_time=0;

pcb_table[i].process_time_slice=0;

pcb_table[i].process_priority=0;

strcpy(pcb_table[i].process_name,"");

}

}

4. 进程队列输出函数display_process_queue( )

该函数有一个输入参数用来指明要显示的进程队列的对首。

在vc++6.0的控制台程序中不能直接控制光标,要想显示整齐的表格,需要自己设计相关函数,我们设计一个print_space( )函数用来输出若干个空格,以便对齐文本。

void print_space(int num){

int i;

for(i=0;i

printf(" ");

}

}

//以表格的形式显示由queue指出的进程队列

void display_process_queue(PCB *queue)

{

PCB *p=queue; //用来遍历进程队列的指针

char buffer[10]; //将整数转换成字符串时用到的缓冲区printf("|--------------|---------|-------|------|-------|----------|\n"); //显示表头

printf("| name | number | start | need | slice | priority |\n");

printf("|--------------|---------|-------|------|-------|----------|\n");

while(p!=NULL){ //显示队列中的每个节点

printf("| ");

printf("%s",p->process_name); //显示进程名称

print_space(23-strlen(p->process_name)); //右边用空格补齐

printf("| ");

printf("%d",p->process_number); //显示进程号

itoa(p->process_number,buffer,10); //整数转换成字符串

print_space(8-strlen(buffer));

printf("| ");

printf("%d",p->process_start_moment); //显示进程启动时刻

itoa(p->process_start_moment,buffer,10);

print_space(6-strlen(buffer));

printf("| ");

printf("%d",p->process_need_time); //显示进程要求运行时间

itoa(p->process_need_time,buffer,10);

print_space(5-strlen(buffer));

printf("| ");

printf("%d",p->process_time_slice); //显示时间片

itoa(p->process_time_slice,buffer,10);

print_space(6-strlen(buffer));

printf("| ");

printf("%d",p->process_priority); //显示优先数

itoa(p->process_priority,buffer,10);

print_space(10-strlen(buffer));

printf("|\n");

p=p->next; //指针下移一个节点}

printf("|--------------|---------|-------|------|-------|----------|\n");

}

编译、链接并运行程序。依次选择功能5、6、7,运行结果都像图1-6这样。这是因为到目前为止就绪队列、运行队列和阻塞队列都为空。

图1-6

5. 创建进程函数create_process( )

为调试方便,要求该函数根据用户从终端输入的数据创建进程,输入数据包括:进程名称、进程启动时刻、要求运行时间、时间片和优先数。如果创建成功则返回新进程PCB的地址;如果不成功则返回空指针,不成功的原因是没有空闲PCB。

如果有空闲PCB,则取空闲PCB链首的PCB作为新进程的PCB,并将空闲PCB链首下移一个节点,提示用户输入数据,根据用户输入的数据填写PCB的数据项,将填写完的PCB连到就绪队列尾部。

//创建进程函数

PCB * create_process( )

{

PCB *p=pcb_free;

if(p==NULL) //若无空闲PCB则返回空指针return NULL;

else //有空闲PCB

{

pcb_free=pcb_free->next; //空闲PCB链首下移一个节点

system("cls");

printf("please enter the following fields:\n"); //提示用户输入以下数据项

printf("| name | start_moment | need_time | time_slice | priority |\n");

scanf("%s%d%d%d%d",p->process_name, //从键盘读取进程名称、

&(p->process_start_moment), //启动时刻、

&(p->process_need_time), //要求运行时间、

&(p->process_time_slice), //时间片、

&(p->process_priority)); //优先数

p->process_number=(process_number+1)%100; //生成进程号(0~100)

process_number++; //下一个进程号

p->next=NULL;

if(pcb_ready==NULL) //若就绪队列为空

pcb_ready=pcb_ready_rear=p; //则新节点为就绪队列唯一节点,对首与队尾相同else //就绪队列不空

{

pcb_ready_rear->next=p; //新建进程插入就绪队列尾部

pcb_ready_rear=p;

}

return p; //返回新进程PCB地址

}

}

6. 阻塞进程函数block_process_by_name( )

根据用户输入的进程名阻塞相应的进程,其处理流程如下:(1)若就绪队列为空则直接返回;

(2)显示就绪队列;

(3)输入要阻塞的进程名称;

(4)在就绪队列中按名称查找要阻塞的进程,若查找不到,则返回;(5)将查找到的进程从就绪队列中删除;

(6)将查找到的进程插入阻塞队列尾部。

7. 唤醒进程函数wakeup_process( )

将阻塞队列的队首进程移入就绪队列尾部。

8. 先来先服务进程调度函数FCFS()

总是选择就绪队列的队首进程运行。

9. 其它函数

其它函数留给同学们自己实现。

1.3.3 参考源程序

2.3.3.1 windows下的参考源程序

#include "process_schedule.h"

int main(int argc,char *argv[ ]){

char select;

init_pcb_table( );

while(1){

printf("|----------MAIN MENU-------------|\n");

printf("| 1:first come first served |\n");

printf("| 2:round robin |\n");

printf("| 3:highest priority first |\n");

printf("| 4:multi_level feedback queue |\n");

printf("| 5:display ready process queue |\n");

printf("| 6:display blocked process queue |\n");

printf("| 7:display running queue |\n");

printf("| a:create a process |\n");

printf("| b:delete a process |\n");

printf("| c:block a process |\n");

printf("| d:wakeup a process |\n");

printf("| 8:exit |\n");

printf("|-----------------------------------|\n");

printf("select a function(1~8,a~d):");

do{

select=(char)getch( );

}while(!((49<=select&&select<=56)||(97<=select&&select<=100)));

system("cls");

switch(select){

case '1':

FCFS( );

break;

case '2':

RR( );

break;

case '3':

HPF( );

break;

case '4':

MFBQ( );

break;

case '5':

printf(" ready queue\n");

display_process_queue(pcb_ready);

break;

case '6':

printf(" blocked queue\n");

display_process_queue(pcb_blocked);

break;

case '7':

printf(" running queue\n");

display_process_queue(pcb_run);

break;

case 'a':

create_process( );

break;

case 'b':

break;

case 'c':

block_process_by_name( );

break;

case 'd':

wakeup_process( );

break;

case '8':

return 0;

}

printf("\nPress any key to return to main menu.");

getch( );

system("cls");

}

return 0;

}

//初始化进程控制块表:进程名为空字符串,进程启动时刻为0,要求运行时间为0,时间片为0,优先数为0. void init_pcb_table( )

{

int i=0;

pcb_free=&pcb_table[0];

pcb_table[MAX_PROCESS-1].next=NULL;

pcb_table[MAX_PROCESS-1].process_number=0;

pcb_table[MAX_PROCESS-1].process_start_moment=0;

pcb_table[MAX_PROCESS-1].process_need_time=0;

pcb_table[MAX_PROCESS-1].process_time_slice=0;

pcb_table[MAX_PROCESS-1].process_priority=0;

strcpy(pcb_table[MAX_PROCESS-1].process_name,"");

for(i=0;i

pcb_table[i].next=&pcb_table[i+1];

pcb_table[i].process_number=0;

pcb_table[i].process_start_moment=0;

pcb_table[i].process_need_time=0;

pcb_table[i].process_time_slice=0;

pcb_table[i].process_priority=0;

strcpy(pcb_table[i].process_name,"");

}

}

//显示进程队列

void display_process_queue(PCB *queue)

{

PCB *p=queue;

char buffer[10];

printf("|--------------|---------|-------|------|-------|----------|\n");

printf("| name | number | start | need | slice | priority |\n");

printf("|--------------|---------|-------|------|-------|----------|\n");

while(p!=NULL){

printf("| ");

printf("%s",p->process_name);

print_space(13-strlen(p->process_name));

printf("| ");

printf("%d",p->process_number);

itoa(p->process_number,buffer,10);

print_space(8-strlen(buffer));

printf("| ");

printf("%d",p->process_start_moment);

itoa(p->process_start_moment,buffer,10);

print_space(6-strlen(buffer));

printf("| ");

printf("%d",p->process_need_time);

itoa(p->process_need_time,buffer,10);

print_space(5-strlen(buffer));

printf("| ");

printf("%d",p->process_time_slice);

itoa(p->process_time_slice,buffer,10);

print_space(6-strlen(buffer));

printf("| ");

printf("%d",p->process_priority);

itoa(p->process_priority,buffer,10);

print_space(9-strlen(buffer));

printf("|\n");

p=p->next;

}

printf("|--------------|---------|-------|------|-------|----------|\n");

}

//显示若干个空格

void print_space(int num){

int i;

for(i=0;i

printf(" ");

}

}

//先来先服务进程调度算法

void FCFS( )

{

if(pcb_ready==NULL)

{

printf("ready queue is empty,no process to run.\n");

}

else

{

pcb_run=pcb_ready;

if(pcb_ready==pcb_ready_rear)

{

pcb_ready=pcb_ready_rear=NULL;

}

else

{

pcb_ready=pcb_ready->next;

}

pcb_run->next=NULL;

}

}

//时间片轮转进程调度算法

void RR( )

{

}

//优先数进程调度算法

void HPF( )

{

}

/多级反馈队列进程调度算法

void MFBQ( )

{

}

//创建进程函数

PCB *create_process( )

{

PCB *p=pcb_free;

if(p==NULL)

return NULL;

else

{

pcb_free=pcb_free->next;

system("cls");

printf("please enter the following fields:\n");

printf("| name | start_moment | need_time | time_slice | priority |\n");

scanf("%s%d%d%d%d",

p->process_name,

&(p->process_start_moment),

&(p->process_need_time),

&(p->process_time_slice),&(p->process_priority));

p->process_number=(process_number+1)%100; //生成进程编号

process_number++;

p->next=NULL;

if(pcb_ready==NULL)

pcb_ready=pcb_ready_rear=p;

else

{

pcb_ready_rear->next=p;

pcb_ready_rear=p;

}

return p;

}

}

//阻塞进程函数

void block_process_by_name( )

{

char process_name[20];

PCB *p=pcb_ready;

PCB *previous_p=pcb_ready;

if(p==NULL)

{

printf("ready queue is empty,no process can be blocked!\n");

return;

}

display_process_queue(pcb_ready);

printf("enter the process name you want to block:\n");

scanf("%s",process_name);

while(p!=NULL){ //在就绪队列中查找指定名称的进程

if(!strcmp(p->process_name,process_name))

break;

previous_p=p;

p=p->next;

}

if(p==NULL) //没有找到指定名称的进程

{

printf("no such a process in ready queue:%s\nyou typed the wrong name\n",process_name);

return;

}

else //找到了指定名称的进程

{

if(p==pcb_ready_rear) //找到的进程是就绪队列中最后一个进程

{

pcb_ready_rear=previous_p;

}

previous_p->next=p->next; //将指定名称的进程从就绪队列中删除

if(pcb_blocked==NULL) //阻塞队列为空

{

pcb_blocked=pcb_blocked_rear=p;

p->next=NULL;

}

else //阻塞队列不空

{

pcb_blocked_rear->next=p;

pcb_blocked_rear=pcb_blocked_rear->next;

p->next=NULL;

}

}

}

//唤醒进程函数

void wakeup_process( )

{

PCB *p=pcb_blocked;

if(pcb_blocked==NULL) //阻塞队列为空,没有进程需要被唤醒

{

printf("blocked queue is empty,no process needs to be wakeuped.\n");

}

else{ //阻塞队列不为空,队首进程需要被唤醒

if(pcb_blocked==pcb_blocked_rear) //阻塞队列中只有一个进程,唤醒后队列为空pcb_blocked=pcb_blocked_rear=NULL;

else //阻塞队列中有多个进程

pcb_blocked=pcb_blocked->next; //删除队首进程

if(pcb_ready==NULL) //就绪队列为空插入在就绪队列首

{

pcb_ready=pcb_ready_rear=p;

p->next=NULL;

}

else //就绪队列不为空则插入就绪队列尾{

pcb_ready_rear->next=p;

pcb_ready_rear=pcb_ready_rear->next;

p->next=NULL;

}

}

}//wakeup

1.3.4 测试程序

1. 运行程序,显示主菜单如图1-1所示。

2. 测试创建进程功能

输入字符a,程序进入创建进程界面,提示你输入五个字段的信息:进程名称、启动时刻、要求运行时间、时间片以及优先数,按照提示依次输入这五个字段的值,如图1-7所示。按回车键后,回到主菜单。可按上述方法再创建三个进程,然后在主菜单中选择功能5,显示进程的就绪队列,如图1-8所示,观察就绪队列是否与预想的一样。注意显示出的就绪队列的number栏是程序自动生成的,每创建一个进程该号加1,加到100后又从0开始循环。图1-8中显示了四个就绪进程,正是你刚刚创建的那些进程。

图1-7 创建进程界面

图1-8 进程就绪队列

3. 测试阻塞进程功能

在主菜单下键入字母c ,进入阻塞进程界面如图1-9所示,屏幕显示就绪队列,并提示你输入要阻塞的进程名称。现在输入要阻塞的进程名称p2,按回车键后

完成对进程p2的阻塞。

为了验证阻塞函数是否正确工

作,在主菜单中键入字符6,

显示阻塞队列如图1-10。可见进程p2已经被阻塞了。按任意键后回到主菜单,在主菜单中键入字符5,显示就绪队列如图1-11,可见就绪队列中少了进程p2。按任意键回到主菜单。

图1-10 阻塞进程队列

图1-11 进程p2被阻塞后的就绪队列

4. 测试唤醒进程功能

图1-9 阻塞进程界面

在主界面下输入字母d 唤醒一个进程。再在主界面下输入数字5,显示就绪队列,然后输入数字6,观察就绪队列和阻塞队列的变化。可以看到进程p2已经被唤醒,因而排到了就绪队列尾部,如图1-12所示,而阻塞队列已经空了。

5. 测试先来先服务进程调度功能

在主界面下输入数字1运行先来先服务进程调度算法,从而选择一个进程运行,再在主界面下输入数字5,显示就绪队列,如图1-13,然后输入数字7,如图1-14,观察就绪队列和运行队列的变化,可见被

选中运行的是队首的进程p1。

图1-14 运行队列

6. 结束测试

在主菜单中键入字符8,结束程序的执行。

图1-12 进程p2被唤醒后的就绪队列

图1-13 p1被选中运行后的就绪队列

设计题目2 读者/写者问题与进程同步

2.1 设计目的

理解临界区和进程互斥的概念,掌握用信号量和PV操作实现进程互斥的方法。

2.2 设计要求

在windows或者linux环境下编写一个控制台应用程序,该程序运行时能创建N个线程,其中既有读者线程又有写者线程,它们按照事先设计好的测试数据进行读写操作。请用信号量和PV操作实现读者/写者问题。

读者/写者问题的描述如下:

有一个被许多进程共享的数据区,这个数据区可以是一个文件,或者主存的一块空间,甚至可以是一组处理器寄存器。有一些只读取这个数据区的进程(reader)和一些只往数据区中写数据的进程(writer)。以下假设共享数据区是文件。这些读者和写者对数据区的操作必须满足以下条件:读—读允许;读—写互斥;写—写互斥。这些条件具体来说就是:(1)任意多的读进程可以同时读这个文件;

(2)一次只允许一个写进程往文件中写;

(3)如果一个写进程正在往文件中写,禁止任何读进程或写进程访问文件;

(4)写进程执行写操作前,应让已有的写者或读者全部退出。这说明当有读者在读文件时不允许写者写文件。

对于读者-写者问题,有三种解决方法:

1、读者优先

除了上述四个规则外,还增加读者优先的规定,当有读者在读文件时,对随后到达的读者和写者,要首先满足读者,阻塞写者。这说明只要有一个读者活跃,那么随后而来的读者都将被允许访问文件,从而导致写者长时间等待,甚至有可能出现写者被饿死的情况。

2、写者优先

除了上述四个规则外,还增加写者优先的规定,即当有读者和写者同时等待时,首先满足写者。当一个写者声明想写文件时,不允许新的读者再访问文件。

3、无优先

除了上述四个规则外,不再规定读写的优先权,谁先等待谁就先使用文件。

2.3设计步骤

2.3.1 算法分析

1、错误的解法

有同学认为,可以将文件视为临界资源,使用临界资源的代码就构成临界区,为了对临界区进行管理,只需设置一个互斥信号量r_w_w,读或者写之前执行P(r_w_w),之后执行V(r_w_w)即可,从而得到图2-1所示的算法描述。

该方法虽然能满足读—写互斥和写—写互斥,但是不满足读—读允许,只要有一个读者在读文件,其他的读者都被阻塞了。

可见,单纯使用互斥信号量不能解决读者/写者问题,还需要引入计数器对读者进行记数。

2、读者优先

如何纠正上述解法中存在的错误呢?

其实,对于相继到达的一批读者,并不是每个读者都需要执行P(r_w_w)和V(r_w_w)。在这批读者中,只有最先到达的读者才需要执行P(r_w_w),与写者竞争对文件的访问权,若执行P(r_w_w)成功则获得了文件的访问权,其他的读者可直接访问文件;同理,只有最后退出临界区的读者需要执行V(r_w_w)来归还文件访问权。

为了记录正在读文件的一批读者的数量,需要设置一个整型变量readercount,每一个读者到达时都要将readercount加1,退出时都要将readercount减1。

由于只要有一个读者在读文件,便不允许写者写文件,所以,仅当readercount=0时,即尚无读者在读文件时,读者才需要执行P(r_w_w)操作。若P(r_w_w)操作成功,读者便可去读文件,相应地,readercount+1。同理,仅当在执行了readercount减1操作后其值为0时,才需要执行V(r_w_w)操作,以便让写者写文件。又因为readercount是一个可被多个读者访问的临界资源,所以应该为它设置一个互斥信号量readercount_mutex.。每个读者在访问readercount之前执行P(readercount_mutex),之后执行V(readercount_mutex)。

通过上述分析得到图2-2所示的算法描述,其中的数字表示语句对应的行号。

下面对该算法的调度效果进行分析。

假设最初没有进程在访问文件。过了一会,就会有很多读者和写者到达。对它们可能有两种调度情形。

操作系统课程设计

课程设计报告 2015~2016学年第一学期 操作系统综合实践课程设计 实习类别课程设计 学生姓名李旋 专业软件工程 学号130521105 指导教师崔广才、祝勇 学院计算机科学技术学院 二〇一六年一月

- 1 -

- 2 -

一、概述 一个目录文件是由目录项组成的。每个目录项包含16B,一个辅存磁盘块(512B)包含32个目录项。在目录项中,第1、2字节为相应文件的外存i节点号,是该文件的内部标识;后14B为文件名,是该文件的外部标识。所以,文件目录项记录了文件内、外部标识的对照关系。根据文件名可以找到辅存i节点号,由此便得到该文件的所有者、存取权、文件数据的地址健在等信息。UNIX 的存储介质以512B为单位划分为块,从0开始直到最大容量并顺序加以编号就成了一个文件卷,也叫文件系统。UNIX中的文件系统磁盘存储区分配图如下: 本次课程设计是要实现一个简单的模拟Linux文件系统。我们在内存中开辟一个虚拟磁盘空间(20MB)作为文件存储器,并将该虚拟文件系统保存到磁盘上(以一个文件的形式),以便下次可以再将它恢复到内存的虚拟磁盘空间中。文件存储空间的管理可采用位示图方法。 二、设计的基本概念和原理 2.1 设计任务 多用户、多级目录结构文件系统的设计与实现。可以实现下列几条命令login 用户登录 logout 退出当前用户 dir 列文件目录 creat 创建文件 delete 删除文件 open 打开文件 close 关闭文件 - 3 -

read 读文件 write 写文件 mkdir 创建目录 ch 改变文件目录 rd 删除目录树 format 格式化文件系统 Exit 退出文件系统 2.2设计要求 1) 多用户:usr1,usr2,usr3,……,usr8 (1-8个用户) 2) 多级目录:可有多级子目录; 3) 具有login (用户登录)4) 系统初始化(建文件卷、提供登录模块) 5) 文件的创建:create (用命令行来实现)6) 文件的打开:open 7) 文件的读:read8) 文件的写:write 9) 文件关闭:close10) 删除文件:delete 11) 创建目录(建立子目录):mkdir12) 改变当前目录:cd 13) 列出文件目录:dir14) 退出:logout 新增加的功能: 15) 删除目录树:rd 16) 格式化文件系统:format 2.3算法的总体思想 - 4 -

操作系统课程设计文件系统管理)

操作系统课程设计Array文件系统管理 学院计算机学院 专业计算机科学与技术 班级 姓名 学号 2013年1月8日 广东工业大学计算机学院制 文件系统管理 一、实验目的 模拟文件系统的实现的基本功能,了解文件系统的基本结构和文件系统的管理方法看,加深了解文件系统的内部功能的实现。通过高级语言编写和实现一个简单的文件系统,模拟文件管理的工作过程,从而对各种文件操作系统命令的实质内容和执行过程有比较深入的了解。 二、实验内容和要求 编程模拟一个简单的文件系统,实现文件系统的管理和控制功能。在用户程序中通过使用文件系统提供的create,open,read,write,close,delete等文件命令,对文件进行操作。 以下报告主要包括: 1.可行性分析 2.需求分析 3.概要设计

4.详细设计 5.测试 6.总结 三、可行性分析 1、技术可行性 对于图形编程还不了解,但是经过本学期的三次实验的练习,可以设计好命令操作界面。利用大二期间学习的数据结构可以模拟出此课程设计的要求。 2、经济可行性 课程设计作为本课程的练习及进一步加深理解。与经济无关,可以不考虑。(零花费,零收益) 3.法律可行性 自己编写的程序,仅为练习,不作其他用途,与外界没什么联系,可行。 四、需求分析 编写程序实现文件系统,主要有以下几点要求: 1、实现无穷级目录管理及文件管理基本操作 2、实现共享“别名” 3、加快了文件检索 五、概要设计 为了克服单级目录所存在的缺点,可以为每一位用户建立一个单独的用户文件目录UFD(User File Directory)。这些文件目录可以具有相似的结构,它由用户所有文件的文件控制块组成。此外,在系统中再建立一个主文件目录MFD (Master File Directory);在主文件目录中,每个用户目录文件都占有一个目

操作系统课程设计报告书

题目1 连续动态内存管理模拟实现 1.1 题目的主要研究内容及预期达到的目标 (1)针对操作系统中内存管理相关理论进行设计,编写程序并进行测试,该程序管理一块虚拟内存。重点分析三种连续动态内存分配算法,即首次适应算法、循环首次适应算法和最佳适应算法。 (2)实现内存分配和回收功能。 1.2 题目研究的工作基础或实验条件 (1)硬件环境:PC机 (2)软件环境:Windows XP,Visual C++ 6.0 1.3 设计思想 首次适应算法的实现:从空闲分区表的第一个表目起查找该表,把最先能够满足要求的空闲区分配给作业,这种方法的目的在于减少查找时间。为适应这种算法,空闲分区表中的空闲分区要按地址由低到高进行排序。该算法优先使用低址部分空闲区,在低址空间造成许多小的空闲区,在高址空间保留大的空闲区。 循环首次适应算法的实现:在分配内存空间时,不再每次从表头开始查找,而是从上次找到空闲区的下一个空闲开始查找,直到找到第一个能满足要求的的空闲区为止,并从中划出一块与请求大小相等的内存空间分配给作业。该算法能使内存中的空闲区分布得较均匀。 最佳适应算法的实现:从全部空闲区中找到能满足作业要求的、且最小的空闲分区,这种方法能使碎片尽量小。为适应此算法,空闲分区表中的空闲分区要按从小到大进行排序,从表头开始查找第一个满足要求的自由分配。 1.4 流程图 内存分配流程图,如图1-1所示。

图1-1 内存分配流程图内存回收流程图,如1-2所示。

图1-2 内存回收流程图 1.5 主要程序代码 (1)分配内存 void allocate(char z,float l) { int i,k; float ad; k=-1; for(i=0;i= l && free_table[i].flag == 1) if(k==-1 || free_table[i].length

操作系统课程设计-模拟文件系统

目录 第1章需求分析 (1) 第2章概要设计 (1) 2.1 系统的主要功能 (1) 2.2系统模块功能结构 (1) 2.3运行环境要求 (2) 2.4数据结构设计 (2) 第3章详细设计 (3) 3.1模块设计 (3) 3.2算法流程图 (3) 第4章系统源代码 (4) 第5章系统测试及调试 (4) 5.1运行结果及分析 (4) 5.2系统测试结论 (5) 第6章总结与体会 (6) 第7章参考文献 (6) 附录 (7)

第1章需求分析 通过模拟文件系统的实现,深入理解操作系统中文件系统的理论知识, 加深对教材中的重要算法的理解。同时通过编程实现这些算法,更好地掌握操作系统的原理及实现方法,提高综合运用各专业课知识的能力;掌握操作系统结构、实现机理和各种典型算法,系统地了解操作系统的设计和实现思路,并了解操作系统的发展动向和趋势。 模拟二级文件管理系统的课程设计目的是通过研究Linux的文件系统结构,模拟设计一个简单的二级文件系统,第一级为主目录文件,第二级为用户文件。 第2章概要设计 2.1 系统的主要功能 1) 系统运行时根据输入的用户数目创建主目录 2) 能够实现下列命令: Login 用户登录 Create 建立文件 Read 读取文件 Write写入文件 Delete 删除文件 Mkdir 建立目录

Cd 切换目录 Logout 退出登录 2.2系统模块功能结构 2.3运行环境要求 操作系统windows xp ,开发工具vc++6.0 2.4数据结构设计 用户结构:账号与密码结构 typedef struct users { char name[8]; char pwd[10]; }users;

操作系统课程设计报告

操作系统课程设计报告

东莞理工学院 操作系统课程设计报告 学院:计算机学院 专业班级: 13软件工程1班 提交时间: 2015/9/14 指导教师评阅意见: . 项目名称:进程与线程管理功能 一、设计目的 用语言来模拟进程和线程管理系统,加深对进程和线程的理解,掌握对进程和线程各种状态和管理的算法原理。

二、环境条件 系统: WindowsXP、VMWare、Ubuntu Linux 语言:C/C++ 开发工具:gcc/g++、Visual C++ 6.0 三、设计内容 1. 项目背景 计算机的硬件资源有限,为了提高内存的利用率和系统的吞吐量,就要根据某种算法来管理进程和线程的状态从而达到目的。 进程与线程管理功能完成基于优先级的抢占式线程调度功能,完成进程虚拟内存管理功能。 进程与线程管理功能 基本要求:完成基于优先级的抢占式线程调度功能,完成进程虚拟内存管理功能。 提高要求:(增加1项就予以加分) (1) 实现多种线程调度算法; (2)通过“公共信箱”进行通信的机制,规定每一封信的大小为128字节,实现两个用户进程之间通过这个“公共信箱”进行通信。 (3) 实现多用户进程并发的虚拟内存管理功能。

(4) 实现用户进程间通信功能,并用生产者/消费者问题测试进程间通信功能的正确性。 (5) 实现改进型Clock页面置换算法。 (6) 实现Cache功能,采用FIFO替换算法。 2. 扩展内容 实现多种线程调度算法:时间片轮转调度算法 四、人员分工 优先级调度算法:钟德新,莫友芝 时间片轮转调度算法:张德华,袁马龙 设计报告由小组队员共同完成。小组成员设计的代码分工如下:钟德新编写的代码:void Prinft(){ PCB *p; system("cls");//清屏 p=run; //运行队列 if(p!=NULL) { p->next=NULL; } cout<<"当前正在运行的进程:"<procname<<"\t\t"<pri<<"\t"<needOftime<<"\t\t"<runtime<<"\t\t"<state<next; } cout<

操作系统课程设计完整版内含代码

操作系统课程设计LRU页面调度算法 学号: 姓名: 学院: 专业: 班级: 指导老师: 日期:

目录 一、实验题目 (1) 二、课程设计的目的 (1) 三、设计内容 (1) 四、设计要求 (1) 五、设计思想 (1) 六、主要数据结构及其说明 (2) 七、硬件支持 (3) 八、源程序文件 (3) 九、程序运行结果 (7) 十、实验体会 (8)

一实验题目 LRU页面调度算法 二课程设计的目的 操作系统课程设计是计算机专业重要的教学环节,它为学生提供了一个既动手又动脑,将课本上的理论知识和实际有机的结合一起,独立分析和解决实际问题的机会。 1.进一步巩固和复习操作系统的基础知识。 2. 培养学生结构化程序、模块化程序设计的方法和能力。 3.提高学生调试程序的技巧和软件设计的能力。 4.提高学生分析问题、解决问题以及综合利用C语言进行程序设计的能力。 三设计内容 程序应模拟实现LRU算法思想,对n个页面实现模拟调度。 四设计要求 1.不同的功能使用不同的函数实现(模块化),对每个函数的功能和调用接口要注释清楚。对程序其它部分也进行必要的注释。 2.对系统进行功能模块分析、画出总流程图和各模块流程图。 3.用户界面要求使用方便、简洁明了、美观大方、格式统一。所有功能可以反复使用,最好使用菜单。 4.通过命令行相应选项能直接进入某个相应菜单选项的功能模块。 5.所有程序需调试通过。 五设计思想 最近最久未使用(LRU)页调度算法是选择最近最久未使用的页面予以淘汰。 算法赋予每个页面一个访问字段,用来记录一个页面自上次被访问以来所经历的时间,当所要访问的页面在内存块中时,就不淘汰页面,否则,淘汰页面中时间最长的,即淘汰最近最久未使用的页面。

操作系统课程设计报告

上海电力学院 计算机操作系统原理 课程设计报告 题目名称:编写程序模拟虚拟存储器管理 姓名:杜志豪.学号: 班级: 2012053班 . 同组姓名:孙嘉轶 课程设计时间:—— 评语: 成绩: 目录 一、设计内容及要求 (4) 1. 1 设计题目 (4) 1.2 使用算法分析: (4)

1. FIFO算法(先进先出淘汰算法) (4) 1. LRU算法(最久未使用淘汰算法) (5) 1. OPT算法(最佳淘汰算法) (5) 分工情况 (5) 二、详细设计 (6) 原理概述 (6) 主要数据结构(主要代码) (6) 算法流程图 (9) 主流程图 (9) Optimal算法流程图 (10) FIFO算法流程图 (10) LRU算法流程图 (11) .1源程序文件名 (11) . 2执行文件名 (11) 三、实验结果与分析 (11) Optimal页面置换算法结果与分析 (11) FIFO页面置换算法结果与分析 (16) LRU页面置换算法结果与分析 (20) 四、设计创新点 (24) 五、设计与总结 (27)

六、代码附录 (27) 课程设计题目 一、设计内容及要求 编写程序模拟虚拟存储器管理。假设以M页的进程分配了N

块内存(N

【精选】操作系统课程设计(文件系统管理)文件

评定等级 操作系统课程设计 文件系统管理 学院计算机学院 专业计算机科学与技术 班级 姓名 学号 2013年1月8日 广东工业大学计算机学院制

文件系统管理 一、实验目的 模拟文件系统的实现的基本功能,了解文件系统的基本结构和文件系统的管理方法看, 加深了解文件系统的内部功能的实现。通过高级语言编写和实现一个简单的文件系统,模拟文件管理的工作过程,从而对各种文件操作系统命令的实质内容和执行过程有比较深入的了 解。 二、实验内容和要求 编程模拟一个简单的文件系统,实现文件系统的管理和控制功能。在用户程序中通过使用文件系统提供的create,open,read,write,close,delete 等文件命令,对文件进行操作。以下报告主要包括: 1.可行性分析 2.需求分析 3.概要设计 4.详细设计 5.测试 6.总结 三、可行性分析 1、技术可行性 对于图形编程还不了解,但是经过本学期的三次实验的练习,可以设计好命令操作界面。利用大二期间学习的数据结构可以模拟出此课程设计的要求。 2、经济可行性 课程设计作为本课程的练习及进一步加深理解。与经济无关,可以不考虑。(零花费,零收益) 3.法律可行性 自己编写的程序,仅为练习,不作其他用途,与外界没什么联系,可行。 四、需求分析 编写程序实现文件系统,主要有以下几点要求: 1、实现无穷级目录管理及文件管理基本操作 2、实现共享“别名” 3、加快了文件检索 五、概要设计 为了克服单级目录所存在的缺点,可以为每一位用户建立一个单独的用户文件目录 UFD (User File Directory )。这些文件目录可以具有相似的结构,它由用户所有文件的文件 控制块组成。此外,在系统中再建立一个主文件目录MFD (Master File Directory );在主文件目录中,每个用户目录文件都占有一个目录项,其目录项中包括用户名和指向该用户目 录的指针。

操作系统课程设计报告

课程设计说明书 设计题目:操作系统课程设计 班级:信息学管理与信息系统2011级 学号: 2 姓名:克乾

山东科技大学2013年12 月11 日

课程设计任务书 学院信息科学与工程专业信息学管理与信息系统班级2011-2 克乾 一、课程设计题目:操作系统课程设计 二、课程设计主要参考资料 (1)Abraham Silberschatz & Peter Baer Galvin & Greg Gagne. Operating System Concepts(第七版影印版). 高等教育. 2007.3. (2)c++面向对象程序设计电子工业 (3)计算机操作系统(第三版)电子科技大学 三、课程设计应解决的主要问题: (1)CPU调度算法的模拟实现 (2)死锁相关算法的实现 (3)磁盘调度算法的实现 四、课程设计相关附件(如:图纸、软件等): (1)程序源代码 (2) 五、任务发出日期:2013-10-1 课程设计完成日期:2014-1-1

指导教师签字:

指导教师对课程设计的评语成绩: 指导教师签字: 年月日

设计1 CPU调度算法的模拟实现一、设计目的 利用C++编写CPU调度算法,实现先来先服务调度算法FCFS、优先级调度算法PS、短作业优先调度算法SJF、时间片轮转调度算法RR的运行过程和实现的结果,针对模拟进程,利用编写的CPU调度算法对需要运行的进程进行调度。进行算法评价,计算平均周转时间和平均等待时间。 二、设计要求 针对模拟进程,利用CPU调度算法进行调度,最后要进行算法评价,计算平均周转时间和平均等待时间,并且输出调度结果和输出算法评价指标。 调度所需的进程参数由输入产生(手工输入或者随机数产生)。 三、设计说明 时间片轮转算法需要输入相应的时间片,所以独立编写一个程序,系统主体结构如下:

操作系统课程设计报告

; 一、概述 课程设计目的、意义: 课程设计目的使学生熟悉文件管理系统的设计方法;加深对所学各种文件操作的了解及其操作方法的特点。通过模拟文件系统的实现,深入理解操作系统中文件系统的理论知识, 加深对教材中的重要算法的理解。同时通过编程实现这些算法,更好地掌握操作系统的原理及实现方法,提高综合运用各专业课知识的能力。 主要任务: 模拟文件系统设计是设计和实现一个简单的文件系统。内容包括: 1.建立文件存储介质的管理机制 2.建立目录(采用一级目录结构) 3.文件系统功能(显示目录、创建、删除、打开、关闭、读、写) ~ 4.文件操作接口(显示目录、创建、删除、打开、关闭、读、写) 二、系统设计 课程设计的系统设计: 本系统模拟一个文件管理系统,要完成对文件的基本操作,文件的基本操作有文件、文件夹的打开、新建、删除和读取写入文件,创建更改目录,列出目录内容等信息。系统建立了文件目录树,存储文件系统中的所有文

件。对于用户名下的文件,用文件目录树的分枝来存贮。采用命令行操作界面很直观,也方便用户进行操作,用户只要按照操作界面所显示的命令来操作就行了。 整体设计框架: 系统初始化界面是由创建用户存储空间,管理文件,退出系统三个模块组成。用户创建由创建用户存储空间,进入目录,删除用户存储空间,显示所有用户存储空间,等模块组成。然后各个模块再由一些小模块组成。其中创建文件,打开关闭文件,读写文件等文件操作模块包括在进入目录模块里面。 三、系统实现 课程设计主要内容的实现程序代码: 《 #include <> #include <> #include <> typedef struct file{ char name[10]; struct file *next; }File; typedef struct content{ ! char name[10]; File *file;

操作系统课程设计报告

东莞理工学院 操作系统课程设计报告学院:计算机学院 专业班级:13软件工程1班 提交时间:2015/9/14 指导教师评阅意见: . 项目名称:进程与线程管理功能 一、设计目的 用语言来模拟进程和线程管理系统,加深对进程和线程的理解,掌握对进程和线程各种状态和管理的算法原理。 二、环境条件 系统:WindowsXP、VMWare、Ubuntu Linux 语言:C/C++ 开发工具:gcc/g++、Visual C++ 6.0 三、设计内容 1. 项目背景

计算机的硬件资源有限,为了提高内存的利用率和系统的吞吐量,就要根据某种算法来管理进程和线程的状态从而达到目的。 进程与线程管理功能完成基于优先级的抢占式线程调度功能,完成进程虚拟内存管理功能。 进程与线程管理功能 基本要求:完成基于优先级的抢占式线程调度功能,完成进程虚拟内存管理功能。 提高要求:(增加1项就予以加分) (1) 实现多种线程调度算法; (2)通过“公共信箱”进行通信的机制,规定每一封信的大小为128字节,实现两个用户进程之间通过这个“公共信箱”进行通信。 (3) 实现多用户进程并发的虚拟内存管理功能。 (4) 实现用户进程间通信功能,并用生产者/消费者问题测试进程间通信功能的正确性。 (5) 实现改进型Clock页面置换算法。 (6) 实现Cache功能,采用FIFO替换算法。 2. 扩展内容 实现多种线程调度算法:时间片轮转调度算法 四、人员分工 优先级调度算法:钟德新,莫友芝 时间片轮转调度算法:张德华,袁马龙 设计报告由小组队员共同完成。小组成员设计的代码分工如下: 钟德新编写的代码:void Prinft(){ PCB *p; system("cls");//清屏 p=run; //运行队列 if(p!=NULL) { p->next=NULL; } cout<<"当前正在运行的进程:"<procname<<"\t\t"<pri<<"\t"<needOftime<<"\t\t"<runtime<<"\t\t"<state<next; } cout<procname<<"\t\t"<pri<<"\t"<needOftime<<"\t\t"<runtime<<"\t\t"<state<next; } cout<

操作系统课程设计

湖南科技大学计算机科学与工程学院 操作系统课程设计报告 ******** *** 目录 实验一 Windows 进程管理 实验二 Linux 进程管理 实验三 互斥与同步 实验四 银行家算法的模拟与实现 实验五 内存管理 指导老师: *** 完成时间: **** ** **

实验六磁盘调度 实验七进程间通信 实验一 Windows进程管理 一、实验目的 1 )学会使用VC编写基本的Win3 2 Consol Application (控制台应用程序)。 2)2)通过创建进程、观察正在运行的进程和终止进程的程序设计和调试操作,进一步熟 悉操作系统的进程概念,理解Windows进程的"一生”。 3)3)通过阅读和分析实验程序,学习创建进程、观察进程、终止进程以及父子进程同步 的基本程序设计方法。 二、实验内容和步骤 (1)编写基本的 Win32 Consol Application 步骤1:登录进入 Windows系统,启动VC++ 6.0。 步骤2:在“ FILE”菜单中单击“ NEW”子菜单,在“ projects ”选项卡中选择 “Win32 ConsolApplication ”,然后在“ Project name 处输入工程名,在“Location ”处输入工程目录。创建一个新的控制台应用程序工程。 步骤3:在“ FILE”菜单中单击“ NEW”子菜单,在“ Files ”选项卡中选择“ C++ Source File ” ,然后在“ File ”处输入C/C++源程序的文件名。 步骤4:将清单1-1所示的程序清单复制到新创建的C/C++源程序中。编译成可执行文件。 步骤5 :在“开始”菜单中单击“程序” -“附件”-“命令提示符”命令,进入Windows“命令提示符”窗口,然后进入工程目录中的 debug子目录,执行编译好的可执行程序,列出运行结果(如果运行不成功,则可能的原因是什么?) 如果运行不成功可能是路径有问题或者没有通过编译。

操作系统课程设计二级文件系统

操作系统课程设计报告 专业:计算机信息处理 学号:09103408 姓名:纪旻材 提交日期:2011-12-28

【设计目的】 1. 课程设计目的是通过一个简单多用户文件系统的设计,加深理解文件系统的内部功能和内部实现。 2. 结合数据结构、程序设计、计算机原理等课程的知识,设计一个二级文件系统,进一步理解操作系统。 3. 通过对实际问题的分析、设计、编程实现,提高学生实际应用、编程的能力 【设计内容】 1、delete 删除文件 2、open 打开文件 3、close 关闭文件 4、write 写文件 【实验环境】 Windows7系统

Visual studio 2010 【相关知识综述】 本文件系统采用两级目录,其中第一级对应于用户账号,第二级对应于用户帐号下的文件。另外,为了简便文件系统未考虑文件共享,文件系统安全以及管道文件与设备文件等特殊内容。 首先应确定文件系统的数据结构:主目录、子目录及活动文件等。主目录和子目录都以文件的形式存放于磁盘,这样便于查找和修改。用户创建的文件,可以编号存储于磁盘上。如:file0,file1,file2…并以编号作为物理地址,在目录中进行登记。 【设计思路】 1 主要数据结构 #define MAXNAME 25 /*the largest length of mfdname,ufdname,filename*/ #define MAXCHILD 50 /*the largest child每个用户名下最多有50个文件*/ #define MAX (MAXCHILD*MAXCHILD) /*the size of fpaddrno*/ typedef struct/*the structure of OSFILE定义主文件*/

操作系统课程设计报告

东莞理工学院 操作系统课程设计报告 学院:计算机学院 专业班级:13软件工程1班 提交时间:2015/9/14 指导教师评阅意见: . 项目名称:进程与线程管理功能 一、设计目的 用语言来模拟进程和线程管理系统,加深对进程和线程的理解,掌握对进程和线程各种状态和管理的算法原理。 二、环境条件

系统:WindowsXP、VMWare、Ubuntu Linux 语言:C/C++ 开发工具:gcc/g++、Visual C++ 6.0 三、设计内容 1. 项目背景 计算机的硬件资源有限,为了提高内存的利用率和系统的吞吐量,就要根据某种算法来管理进程和线程的状态从而达到目的。 进程与线程管理功能完成基于优先级的抢占式线程调度功能,完成进程虚拟内存管理功能。 进程与线程管理功能 基本要求:完成基于优先级的抢占式线程调度功能,完成进程虚拟内存管理功能。 提高要求:(增加1项就予以加分) (1) 实现多种线程调度算法; (2)通过“公共信箱”进行通信的机制,规定每一封信的大小为128字节,实现两个用户进程之间通过这个“公共信箱”进行通信。 (3) 实现多用户进程并发的虚拟内存管理功能。 (4) 实现用户进程间通信功能,并用生产者/消费者问题测试进程间通信功能的正确性。 (5) 实现改进型Clock页面置换算法。 (6) 实现Cache功能,采用FIFO替换算法。

2. 扩展内容 实现多种线程调度算法:时间片轮转调度算法 四、人员分工 优先级调度算法:钟德新,莫友芝 时间片轮转调度算法:张德华,袁马龙 设计报告由小组队员共同完成。小组成员设计的代码分工如下:钟德新编写的代码:void Prinft(){ PCB *p; system("cls");//清屏 p=run; //运行队列 if(p!=NULL) { p->next=NULL; } cout<<"当前正在运行的进程:"<procname<<"\t\t"<pri<<"\t"<needOftime<<"\t\t"<runtime<<"\t\t"<state<next; } cout<procname<<"\t\t"<pri<<"\t"<needOftime<<"\t\t"<runtime<<"\t\t"<state<next; } cout<procname<<"\t\t"<pri<<"\t"<needOftime<<"\t\t"<runtime<<"\t\t"<state<

操作系统(一个小型操作系统的设计与实现)课程设计

南通大学计算机科学与技术学院操作系统课程设计报告 专业: 学生姓名: 学号: 时间:

操作系统模拟算法课程设计报告 设计要求 将本学期三次的实验集成实现: A.处理机管理; B.存储器管理; C.虚拟存储器的缺页调度。 设计流程图 主流程图 开始的图形界面 处理机管理存储器管理缺页调度 先来先服务时 间 片 轮 转 首 次 适 应 法 最 佳 适 应 法 先 进 先 出 L R U 算 法

A.处理机调度 1)先来先服务FCFS N Y 先来先服务算法流程 开始 初始化进程控制块,让进程控制块按进程到达先后顺序让进程排队 调度数组中首个进程,并让数组中的下一位移到首位 计算并打印进程的完成时刻、周转时间、带权周转时间 其中:周转时间 = 完成时间 - 到达时间 带权周转时间=周转时间/服务时间 更改计时器的当前时间,即下一刻进程的开始时间 当前时间=前一进程的完成时间+其服务时间 数组为空 结束

2)时间片轮转法 开始 输入进程总数 指针所指的进程是 否结束 输入各进程信息 输出为就绪状态的进程的信息 更改正在运行的进程的已运行时间 跳过已结束的程序 结束 N 指向下一个进程 Y 如果存在下一个进程的话 Y N 输出此时为就绪状态的进程的信息 时间片轮转算法流程图

B.存储器管理(可变式分区管理) 1)首次适应法 分配流程图 申请xkb内存 由链头找到第一个空闲区 分区大小≥xkb? 大于 分区大小=分区大小-xkb,修改下一个空闲区的后向指针内容为(后向指针)+xkb;修改上一个空闲区的前向指针为(前向指针)+xkb 将该空闲区从链中摘除:修改下一个空闲区的后向地址=该空闲区后向地址,修改上一个空闲区的前向指针为该空闲区的前向指针 等于 小于延链查找下 一个空闲区 到链尾 了? 作业等待 返回是 否 登记已分配表 返回分配给进程的内存首地址 开始

操作系统课程设计(文件系统)

操作系统课程设计 班级: 姓名: 学号: 使用语言:C++ 指导老师: 学院:

一、系统要求 1、实验目的 通过一个简单多用户文件系统的设计,加深理解文件系统的内部功能及内部实现。 2、实验内容 为linux系统设计一个简单的二级文件系统。要求做到以下几点: (1)可以实现下列几条命令(至少4条); login 用户登陆 dir 列文件目录 create 创建文件 delete 删除文件 open 打开文件 close 关闭文件 read 读文件 write 写文件 (2)列目录时要列出文件名、物理地址、保护码和文件长度; (3)源文件可以进行读写保护。 二、系统分析 1、设计思想 本文件为二级文件系统,即要实现对文件的增删改查,同时又具备登陆系统、注册用户的功能,各个用户之间的文件系统互不干扰。 本文件系统采用两级目录,其中第一级对应于用户账号,第二级对应于用户帐号下的文件。另外,为了简便文件系统未考虑文件共享,文件系统安全以及管道文件与设备文件等特殊内容。 系统采用结构体来存储用户、文件目录、文件数据内容: 0 48*5 48*5+44*50 48*5+44*50+264*200 每个分区都是由结构体组成,每个个去的结构体的个数由格式化系统是决定。整个系统的编码构成主要分为:

Allstruct.h 定义了每个分区的结构体; Mysys.h 声明了对系统操作的各种方法; Myuserfile.h 声明了对文件操作的各种方法; Mymain.cpp 整个系统的主函数,操作入口; Mysys.cpp 包含了mysys.h,实现了操作系统的各种方法;Myuserfile.cpp 包含了myuserfile.h,实现了操作文件的各种方法; 2、主要数据结构 Allstruct.h文件的内容: struct s_user //用户区结构体 { long isuse; //是否使用 char name[20]; //用户名 char psd[20]; //密码 long address; //目录地址 }; struct s_list //目录结构体 { long isuse; //是否使用 char name[20]; //文件名字 long myaddress; //本条目录地址 long pointaddress; //指向的文件的地址 long isfile; //是否锁定 long pointsize; //目标文件的大小 long nextaddress; //下条目录的地址 }; struct s_file //文件结构体 { long isuse; //是否使用 char content[256]; //文件内容 long next; //下个文件块地址 };

操作系统课程设计报告

操作系统课程设计实验报告 实验名称:进程控制 姓名/学号: 一、实验目的 学习、理解和掌握Linux与windows的进行控制系统调用的功能,熟悉主要的几个系统调用命令的格式和如何利用系统调用命令进行编程。通过学习,理解如何创建一个进程、改变进程执行的程序、进程和线程终止以及父子进程的同步等,从而提高对进程和线程控制系统调用的编程能力。 二、实验内容 设计并实现Unix的“time”命令。“mytime”命令通过命令行参数接受要运行的程序,创建一个独立的进程来运行该程序,并记录程序运行的时间。 三、实验环境 CPU: Inter ×2 2.10GHz RAM: 3.00GB Windows 7 旗舰版 Linux Ubuntu 10.04 编译: VS2010 四、程序设计与实现 4.1进程控制系统的调用 4.1.1 windows进程控制调用程序中使用的数据结构及主要符号说明 SYSTEMTIME starttime,endtime; //进程开始时间和结束时间 PROCESS_INFORMATION pi //该结构返回有关新进程及 //其主线程的信息 STARTUPINFO si //该结构用于指定新进程的主窗口特性4.1.2 linux进程控制调用程序中使用的数据结构及主要符号说明 struct timeval starttime,endtime //进程开始时间和结束时间 pid_t pid //进程标志符

4.2 程序流程图 图1 windows进程控制调用图2 linux进程控制调用程序运行流程图程序运行流程图 五、实验结果和分析 5.1 windows实验结果和分析

操作系统课程设计

计算机科学技术学院 操作系统原理课程设计报告 题目:进程管理系统 专业: 班级: 姓名: 学号: 指导老师: 年月日

《操作系统原理》课程设计任务书 一、课程设计题目(任选一个题目) 1.模拟进程管理 2.模拟处理机调度 3.模拟存储器管理 4.模拟文件系统 5.模拟磁盘调度 二、设计目的和要求 1.设计目的 《操作系统原理》课程设计是网络工程专业实践性环节之一,是学习完《操作系统原理》课程后进行的一次较全面的综合练习。其目的在于加深对操作系统的理论、方法和基础知识的理解,掌握操作系统结构、实现机理和各种典型算法,系统地了解操作系统的设计和实现思路,培养学生的系统设计能力,并了解操作系统的发展动向和趋势。 2.基本要求: (1)选择课程设计题目中的一个课题,独立完成。 (2)良好的沟通和合作能力 (3)充分运用前序课所学的软件工程、程序设计、数据结构等相关知识 (4)充分运用调试和排错技术 (5)简单测试驱动模块和桩模块的编写 (6)查阅相关资料,自学具体课题中涉及到的新知识。 (7)课题完成后必须按要求提交课程设计报告,格式规范,内容详实。 三、设计内容及步骤 1.根据设计题目的要求,充分地分析和理解问题,明确问题要求做什么。

2.根据实现的功能,划分出合理的模块,明确模块间的关系。 3.编程实现所设计的模块。 4.程序调试与测试。采用自底向上,分模块进行,即先调试低层函数。能够熟练掌握调试工具的各种功能,设计测试数据确定疑点,通过修改程序来证实它或绕过它。调试正确后,认真整理源程序及其注释,形成格式和风格良好的源程序清单和结果; 5.结果分析。程序运行结果包括正确的输入及其输出结果和含有错误的输入及其输出结果。 6.编写课程设计报告; 设计报告要求:A4纸,详细设计部分主要叙述本人的工作内容 设计报告的格式: (1)封面(题目、指导教师、专业、班级、姓名、学号) (2)设计任务书 (3)目录 (4)需求分析 (5)概要设计 (6)详细设计(含主要代码) (7)调试分析、测试结果 (8)用户使用说明 (9)附录或参考资料 四、进度安排 设计在学期的第15、16周进行,时间安排如下:

操作系统课程设计模拟文件系统

操作系统课程设计模拟文 件系统 Newly compiled on November 23, 2020

目录第1章需求分析 (1) 第2章概要设计 (1) 系统的主要功能 (1) 系统模块功能结构 (1) 运行环境要求 (2) 数据结构设计 (2) 第3章详细设计 (3) 模块设计 (3) 算法流程图 (3) 第4章系统源代码 (4) 第5章系统测试及调试 (4) 运行结果及分析 (4) 系统测试结论 (5) 第6章总结与体会 (6) 第7章参考文献 (6) 附录 (7) 第1章需求分析 通过模拟文件系统的实现,深入理解操作系统中文件系统的理论知识, 加深对教材中的重要算法的理解。同时通过编程实现这些算法,更好地掌握操作系统的原理及实现方法,提高综合运用各专业课知识的能力;掌握操作系统结构、实现机理和各种典型算法,系统地了解操作系统的设计和实现思路,并了解操作系统的发展动向和趋势。

模拟二级文件管理系统的课程设计目的是通过研究Linux的文件系统结构,模拟设计一个简单的二级文件系统,第一级为主目录文件,第二级为用户文件。 第2章概要设计 系统的主要功能 1) 系统运行时根据输入的用户数目创建主目录 2) 能够实现下列命令: Login 用户登录 Create 建立文件 Read 读取文件 Write 写入文件 Delete 删除文件 Mkdir 建立目录 Cd 切换目录 Logout 退出登录 系统模块功能结构 运行环境要求 操作系统windows xp ,开发工具vc++ 数据结构设计 用户结构:账号与密码结构 typedef struct users { char name[8]; char pwd[10]; }users;

计算机操作系统课程设计

计算机操作系统课程设计 班级:计091-1 姓名: 学号: 使用语言:C++ 指导老师: 学院:

一、系统要求 1、实验目的 通过一个简单多用户文件系统的设计,加深理解文件系统的内部功能及内部实现。 2、实验内容 为linux系统设计一个简单的二级文件系统。要求做到以下几点: (1)可以实现下列几条命令(至少4条); login 用户登陆 dir 列文件目录 create 创建文件 delete 删除文件 open 打开文件 close 关闭文件 read 读文件 write 写文件 (2)列目录时要列出文件名、物理地址、保护码和文件长度; (3)源文件可以进行读写保护。

二、系统分析 1、设计思想 本文件为二级文件系统,即要实现对文件的增删改查,同时又具备登陆系统、注册用户的功能,各个用户之间的文件系统互不干扰。 本文件系统采用两级目录,其中第一级对应于用户账号,第二级对应于用户帐号下的文件。另外,为了简便文件系统未考虑文件共享,文件系统安全以及管道文件与设备文件等特殊内容。 系统采用结构体来存储用户、文件目录、文件数据内容: 0 48*5 48*5+44*50 48*5+44*50+264*200 每个分区都是由结构体组成,每个个去的结构体的个数由格式化系统是决定。

整个系统的编码构成主要分为: Allstruct.h 定义了每个分区的结构体; Mysys.h 声明了对系统操作的各种方法;Myuserfile.h 声明了对文件操作的各种方法; Mymain.cpp 整个系统的主函数,操作入口; Mysys.cpp 包含了mysys.h,实现了操作系统的各种方法;Myuserfile.cpp 包含了myuserfile.h,实现了操作文件的各种方法; 2、主要数据结构 Allstruct.h文件的内容: struct s_user //用户区结构体 { long isuse; //是否使用 char name[20]; //用户名 char psd[20]; //密码 long address; //目录地址 };

相关主题
文本预览
相关文档 最新文档