SSTF磁盘调度算法操作系统课程设计报告2.docx
《SSTF磁盘调度算法操作系统课程设计报告2.docx》由会员分享,可在线阅读,更多相关《SSTF磁盘调度算法操作系统课程设计报告2.docx(10页珍藏版)》请在冰豆网上搜索。
SSTF磁盘调度算法操作系统课程设计报告2
SSTF磁盘调度算法操作系统课程设计报告_
(2)
哈尔滨理工大学
课 程 设 计
(课程名称)
题 目:
SSTF磁盘调度算法
班 级:
姓 名:
指导教师:
系主任:
2014年03月01日
1SSTF磁盘调度算法课程设计
1.1题目分析
SSTF磁盘调度算法问题是操作系统中的一个重要问题。
主要要求访问的磁道与当前磁头所在磁道距离最近,以使每次的寻道时间最短。
故SSTF较之FCFS有更好的寻道性能。
1.2数据结构
SSTF磁盘调度算法问题中涉及的数据结构是定义数组str[],存放输入的数据,用str[i]表示输入第i+1个数据,数组cidao[]和str[]意义一样。
全局变量n,表示磁道的最大个数,now表示当前磁道号,全局变量sum和ave,表示总的寻道时间和平均寻道长度。
用变量i和j,表示第i+1和j+1磁道,变量k表示任意磁道,变量d表示选择移动的方向,有两个取值1表示向外,0表示向内。
用伪代码表示如下:
int scan(Linklist L,int Current){
LNode *p,*q,*s;
float sum=0;
if(L->next!
=NULL){
p=L->next;
while(p->datap=p->next; } 用主要代码表示如下:Now=printnow(0;if(cidao[m-i]<=now)sum=printout(cidao,now,m);if(cidao[0]>=now)sum=printin(cidao,now,m);if(now>cidao[0]@@now{Count<<”磁盘扫描序列为:”;While(cidao[k]{k+1;}i=k-1;r=k;While(i>=0)&&(r{if(now-cidao[i]<=(cidao[r]-now))Sum=prints(cidao,now,m,i,r);Elsesum=printl(cidao,now,m,i,r)1.3流程图 1.4实现技术为实现上述设计,采用C++语言,VS2008开发环境。具体采用的技术如下:(1)数组的寻找及其下表的寻找与遍历(2)数组的排序实现步骤如下:(1)根据移动方向,针对数组内值进行磁道移动(2)对值与值之间进行相见取出磁道移动距离并且进行相干的计算运行结果如下: 1.5设计结论和心得通过课程设计得到如下结论:(1)磁盘,是一种很重要也很常用的外设,其分配也有一定的分配策略。在操作系统中,作业对磁盘的请求常常要排队,由此需要一些高效率的磁盘分配策略算法。(2)最短寻道时间优先算法优先选择距离当前磁头位置最近的作业磁道请求,可以使得每次寻道时所用的时间都最短,但不能保证平均周转时间及带权周转时间最短;有如下几点心得体会:(1)此次课程设计,是我对磁盘调度算法和原理有了更深刻的理解,对于理论在实践中的应用也有了一定的了解。(2)对于我以后的学习和工作有巨大的帮助,课程设计反映的是一个从理论到实际的应用过程,但是更远一点可以联系到以后的毕业之后从学校步入社会的的过程,对于学习编程的学生,课程设计是相当有意义的,所以有些问题要不断的去实践,变换思维。最终有所收获。 2Linux代码分析为了进一步了解操作系统内核,学习了Linux操作系统的进程同步。主要源代码如下复制进程的页目录页表。int copy_page_tables(unsigned long from,unsigned long to,long size) { unsigned long * from_page_table; unsigned long * to_page_table; unsigned long this_page; unsigned long * from_dir, * to_dir; unsigned long nr; // 源地址和目的地址都需要是4Mb 的倍数。否则出错,死机。if ((from&0x3fffff) || (to&0x3fffff)) panic("copy_page_tables called with wrong alignment"); // 取得源地址和目的地址的目录项(from_dir 和to_dir)。from_dir = (unsigned long *) ((from>>20) & 0xffc); /* _pg_dir = 0 */ to_dir = (unsigned long *) ((to>>20) & 0xffc); // 计算要复制的内存块占用的页表数(也即目录项数)。size = ((unsigned) (size+0x3fffff)) >// 下面开始对每个占用的页表依次进行复制操作。Out of m emory, see freeing */ > 22;for( size-->0 from_dir++,to_dir++) { // 如果目的目录项指定的页表已经存在(P=1),则出错,死机。 if (1 & *to_dir) panic("copy_page_tables: already exist"); // 如果此源目录项未被使用,则不用复制对应页表,跳过。if (!(1 & *from_dir)) continue; // 取当前源目录项中页表的地址from_page_table。from_page_table = (unsigned long *) (0xfffff000 & *from_dir); // 为目的页表取一页空闲内存,如果返回是0 则说明没有申请到空闲内存页面。返回值=-1,退出。if (!(to_page_table = (unsigned long *) get_free_page())) return -1; /* Out of memory, see freeing */// 设置目的目录项信息7 是标志信息,表示(Usr, R/W, Present)。*to_dir = ((unsigned long) to_page_table) | 7; // 针对当前处理的页表,设置需复制的页面数。如果是在内核空间,则仅需复制160 页,否则需要// 复制1 个页表中的所有1024 页面nr = (from==0)?0xA0:1024; // 对于当前页表,开始复制指定数目nr 个内存页面。for ( nr-- > 0 from_page_table++,to_page_table++) { this_page = *from_page_table; // 取源页表项内容。if (!(1 & this_page)) // 如果当前源页面没有使用,则不用复制。continue; // 复位页表项中R/W 标志置0)。(如果U/S位是0,则R/W 就没有作用。如果U/S 是1,而R/W 是0,// 那么运行在用户层的代码就只能读页面。如果U/S 和R/W 都置位,则就有写的权限。) this_page &= ~2; *to_page_table = this_page; // 将该页表项复制到目的页表中。// 如果该页表项所指页面的地址在1M 以上,则需要设置内存页面映射数组mem_map[],于是计算// 页面号,并以它为索引在页面映射数组相应项中增加引用次数。if (this_page > LOW_MEM) *from_page_table = this_page; //令源页表项也只读[??]。this_page -= LOW_MEM; this_page >>= 12; mem_map[this_page]++; } } } invalidate(); // 刷新页变换高速缓冲。return 0; 窗体顶端2.1功能说明这一段程序的主要功能为:(1)复制进程的页目录页表;2.2接口说明本程序的输入参数为:unsigned long from,unsigned long to,long size输出结果:为将进程的页目录页表复制:2.3局部数据结构本程序共有5个局部变量及数据结构,其类型定义及语义如下:unsignedlong*from_page_table;//记录复制文件的位置unsignedlong*to_page_table;//目标文件位置unsignedlongthis_page;//页目录unsignedlong*from_dir,*to_dir;/页表unsignedlongnr;记录页表页面数2.4流程图本程序的流程图如图2所示 图2 程序流程图2.5以实例说明运行过程例如,当有多个进程到达,P表示生产者进程,C表示消费者进程,到达序列为PPPCCPP时,根据分析,运行结果应为:例如,系统需要交换页面时,需要对页面复制,根据分析,运行结果应为:交换成功。返回值为零 实际运行结果如下: 返回值为零,页面已交换 。。。实际运行结果如下:
p=p->next;
}
用主要代码表示如下:
Now=printnow(0;
if(cidao[m-i]<=now)
sum=printout(cidao,now,m);
if(cidao[0]>=now)sum=printin(cidao,now,m);
if(now>cidao[0]@@now{Count<<”磁盘扫描序列为:”;While(cidao[k]{k+1;}i=k-1;r=k;While(i>=0)&&(r{if(now-cidao[i]<=(cidao[r]-now))Sum=prints(cidao,now,m,i,r);Elsesum=printl(cidao,now,m,i,r)1.3流程图 1.4实现技术为实现上述设计,采用C++语言,VS2008开发环境。具体采用的技术如下:(1)数组的寻找及其下表的寻找与遍历(2)数组的排序实现步骤如下:(1)根据移动方向,针对数组内值进行磁道移动(2)对值与值之间进行相见取出磁道移动距离并且进行相干的计算运行结果如下: 1.5设计结论和心得通过课程设计得到如下结论:(1)磁盘,是一种很重要也很常用的外设,其分配也有一定的分配策略。在操作系统中,作业对磁盘的请求常常要排队,由此需要一些高效率的磁盘分配策略算法。(2)最短寻道时间优先算法优先选择距离当前磁头位置最近的作业磁道请求,可以使得每次寻道时所用的时间都最短,但不能保证平均周转时间及带权周转时间最短;有如下几点心得体会:(1)此次课程设计,是我对磁盘调度算法和原理有了更深刻的理解,对于理论在实践中的应用也有了一定的了解。(2)对于我以后的学习和工作有巨大的帮助,课程设计反映的是一个从理论到实际的应用过程,但是更远一点可以联系到以后的毕业之后从学校步入社会的的过程,对于学习编程的学生,课程设计是相当有意义的,所以有些问题要不断的去实践,变换思维。最终有所收获。 2Linux代码分析为了进一步了解操作系统内核,学习了Linux操作系统的进程同步。主要源代码如下复制进程的页目录页表。int copy_page_tables(unsigned long from,unsigned long to,long size) { unsigned long * from_page_table; unsigned long * to_page_table; unsigned long this_page; unsigned long * from_dir, * to_dir; unsigned long nr; // 源地址和目的地址都需要是4Mb 的倍数。否则出错,死机。if ((from&0x3fffff) || (to&0x3fffff)) panic("copy_page_tables called with wrong alignment"); // 取得源地址和目的地址的目录项(from_dir 和to_dir)。from_dir = (unsigned long *) ((from>>20) & 0xffc); /* _pg_dir = 0 */ to_dir = (unsigned long *) ((to>>20) & 0xffc); // 计算要复制的内存块占用的页表数(也即目录项数)。size = ((unsigned) (size+0x3fffff)) >// 下面开始对每个占用的页表依次进行复制操作。Out of m emory, see freeing */ > 22;for( size-->0 from_dir++,to_dir++) { // 如果目的目录项指定的页表已经存在(P=1),则出错,死机。 if (1 & *to_dir) panic("copy_page_tables: already exist"); // 如果此源目录项未被使用,则不用复制对应页表,跳过。if (!(1 & *from_dir)) continue; // 取当前源目录项中页表的地址from_page_table。from_page_table = (unsigned long *) (0xfffff000 & *from_dir); // 为目的页表取一页空闲内存,如果返回是0 则说明没有申请到空闲内存页面。返回值=-1,退出。if (!(to_page_table = (unsigned long *) get_free_page())) return -1; /* Out of memory, see freeing */// 设置目的目录项信息7 是标志信息,表示(Usr, R/W, Present)。*to_dir = ((unsigned long) to_page_table) | 7; // 针对当前处理的页表,设置需复制的页面数。如果是在内核空间,则仅需复制160 页,否则需要// 复制1 个页表中的所有1024 页面nr = (from==0)?0xA0:1024; // 对于当前页表,开始复制指定数目nr 个内存页面。for ( nr-- > 0 from_page_table++,to_page_table++) { this_page = *from_page_table; // 取源页表项内容。if (!(1 & this_page)) // 如果当前源页面没有使用,则不用复制。continue; // 复位页表项中R/W 标志置0)。(如果U/S位是0,则R/W 就没有作用。如果U/S 是1,而R/W 是0,// 那么运行在用户层的代码就只能读页面。如果U/S 和R/W 都置位,则就有写的权限。) this_page &= ~2; *to_page_table = this_page; // 将该页表项复制到目的页表中。// 如果该页表项所指页面的地址在1M 以上,则需要设置内存页面映射数组mem_map[],于是计算// 页面号,并以它为索引在页面映射数组相应项中增加引用次数。if (this_page > LOW_MEM) *from_page_table = this_page; //令源页表项也只读[??]。this_page -= LOW_MEM; this_page >>= 12; mem_map[this_page]++; } } } invalidate(); // 刷新页变换高速缓冲。return 0; 窗体顶端2.1功能说明这一段程序的主要功能为:(1)复制进程的页目录页表;2.2接口说明本程序的输入参数为:unsigned long from,unsigned long to,long size输出结果:为将进程的页目录页表复制:2.3局部数据结构本程序共有5个局部变量及数据结构,其类型定义及语义如下:unsignedlong*from_page_table;//记录复制文件的位置unsignedlong*to_page_table;//目标文件位置unsignedlongthis_page;//页目录unsignedlong*from_dir,*to_dir;/页表unsignedlongnr;记录页表页面数2.4流程图本程序的流程图如图2所示 图2 程序流程图2.5以实例说明运行过程例如,当有多个进程到达,P表示生产者进程,C表示消费者进程,到达序列为PPPCCPP时,根据分析,运行结果应为:例如,系统需要交换页面时,需要对页面复制,根据分析,运行结果应为:交换成功。返回值为零 实际运行结果如下: 返回值为零,页面已交换 。。。实际运行结果如下:
{
Count<<”磁盘扫描序列为:
”;
While(cidao[k]{k+1;}i=k-1;r=k;While(i>=0)&&(r{if(now-cidao[i]<=(cidao[r]-now))Sum=prints(cidao,now,m,i,r);Elsesum=printl(cidao,now,m,i,r)1.3流程图 1.4实现技术为实现上述设计,采用C++语言,VS2008开发环境。具体采用的技术如下:(1)数组的寻找及其下表的寻找与遍历(2)数组的排序实现步骤如下:(1)根据移动方向,针对数组内值进行磁道移动(2)对值与值之间进行相见取出磁道移动距离并且进行相干的计算运行结果如下: 1.5设计结论和心得通过课程设计得到如下结论:(1)磁盘,是一种很重要也很常用的外设,其分配也有一定的分配策略。在操作系统中,作业对磁盘的请求常常要排队,由此需要一些高效率的磁盘分配策略算法。(2)最短寻道时间优先算法优先选择距离当前磁头位置最近的作业磁道请求,可以使得每次寻道时所用的时间都最短,但不能保证平均周转时间及带权周转时间最短;有如下几点心得体会:(1)此次课程设计,是我对磁盘调度算法和原理有了更深刻的理解,对于理论在实践中的应用也有了一定的了解。(2)对于我以后的学习和工作有巨大的帮助,课程设计反映的是一个从理论到实际的应用过程,但是更远一点可以联系到以后的毕业之后从学校步入社会的的过程,对于学习编程的学生,课程设计是相当有意义的,所以有些问题要不断的去实践,变换思维。最终有所收获。 2Linux代码分析为了进一步了解操作系统内核,学习了Linux操作系统的进程同步。主要源代码如下复制进程的页目录页表。int copy_page_tables(unsigned long from,unsigned long to,long size) { unsigned long * from_page_table; unsigned long * to_page_table; unsigned long this_page; unsigned long * from_dir, * to_dir; unsigned long nr; // 源地址和目的地址都需要是4Mb 的倍数。否则出错,死机。if ((from&0x3fffff) || (to&0x3fffff)) panic("copy_page_tables called with wrong alignment"); // 取得源地址和目的地址的目录项(from_dir 和to_dir)。from_dir = (unsigned long *) ((from>>20) & 0xffc); /* _pg_dir = 0 */ to_dir = (unsigned long *) ((to>>20) & 0xffc); // 计算要复制的内存块占用的页表数(也即目录项数)。size = ((unsigned) (size+0x3fffff)) >// 下面开始对每个占用的页表依次进行复制操作。Out of m emory, see freeing */ > 22;for( size-->0 from_dir++,to_dir++) { // 如果目的目录项指定的页表已经存在(P=1),则出错,死机。 if (1 & *to_dir) panic("copy_page_tables: already exist"); // 如果此源目录项未被使用,则不用复制对应页表,跳过。if (!(1 & *from_dir)) continue; // 取当前源目录项中页表的地址from_page_table。from_page_table = (unsigned long *) (0xfffff000 & *from_dir); // 为目的页表取一页空闲内存,如果返回是0 则说明没有申请到空闲内存页面。返回值=-1,退出。if (!(to_page_table = (unsigned long *) get_free_page())) return -1; /* Out of memory, see freeing */// 设置目的目录项信息7 是标志信息,表示(Usr, R/W, Present)。*to_dir = ((unsigned long) to_page_table) | 7; // 针对当前处理的页表,设置需复制的页面数。如果是在内核空间,则仅需复制160 页,否则需要// 复制1 个页表中的所有1024 页面nr = (from==0)?0xA0:1024; // 对于当前页表,开始复制指定数目nr 个内存页面。for ( nr-- > 0 from_page_table++,to_page_table++) { this_page = *from_page_table; // 取源页表项内容。if (!(1 & this_page)) // 如果当前源页面没有使用,则不用复制。continue; // 复位页表项中R/W 标志置0)。(如果U/S位是0,则R/W 就没有作用。如果U/S 是1,而R/W 是0,// 那么运行在用户层的代码就只能读页面。如果U/S 和R/W 都置位,则就有写的权限。) this_page &= ~2; *to_page_table = this_page; // 将该页表项复制到目的页表中。// 如果该页表项所指页面的地址在1M 以上,则需要设置内存页面映射数组mem_map[],于是计算// 页面号,并以它为索引在页面映射数组相应项中增加引用次数。if (this_page > LOW_MEM) *from_page_table = this_page; //令源页表项也只读[??]。this_page -= LOW_MEM; this_page >>= 12; mem_map[this_page]++; } } } invalidate(); // 刷新页变换高速缓冲。return 0; 窗体顶端2.1功能说明这一段程序的主要功能为:(1)复制进程的页目录页表;2.2接口说明本程序的输入参数为:unsigned long from,unsigned long to,long size输出结果:为将进程的页目录页表复制:2.3局部数据结构本程序共有5个局部变量及数据结构,其类型定义及语义如下:unsignedlong*from_page_table;//记录复制文件的位置unsignedlong*to_page_table;//目标文件位置unsignedlongthis_page;//页目录unsignedlong*from_dir,*to_dir;/页表unsignedlongnr;记录页表页面数2.4流程图本程序的流程图如图2所示 图2 程序流程图2.5以实例说明运行过程例如,当有多个进程到达,P表示生产者进程,C表示消费者进程,到达序列为PPPCCPP时,根据分析,运行结果应为:例如,系统需要交换页面时,需要对页面复制,根据分析,运行结果应为:交换成功。返回值为零 实际运行结果如下: 返回值为零,页面已交换 。。。实际运行结果如下:
{k+1;}i=k-1;r=k;
While(i>=0)&&(r{if(now-cidao[i]<=(cidao[r]-now))Sum=prints(cidao,now,m,i,r);Elsesum=printl(cidao,now,m,i,r)1.3流程图 1.4实现技术为实现上述设计,采用C++语言,VS2008开发环境。具体采用的技术如下:(1)数组的寻找及其下表的寻找与遍历(2)数组的排序实现步骤如下:(1)根据移动方向,针对数组内值进行磁道移动(2)对值与值之间进行相见取出磁道移动距离并且进行相干的计算运行结果如下: 1.5设计结论和心得通过课程设计得到如下结论:(1)磁盘,是一种很重要也很常用的外设,其分配也有一定的分配策略。在操作系统中,作业对磁盘的请求常常要排队,由此需要一些高效率的磁盘分配策略算法。(2)最短寻道时间优先算法优先选择距离当前磁头位置最近的作业磁道请求,可以使得每次寻道时所用的时间都最短,但不能保证平均周转时间及带权周转时间最短;有如下几点心得体会:(1)此次课程设计,是我对磁盘调度算法和原理有了更深刻的理解,对于理论在实践中的应用也有了一定的了解。(2)对于我以后的学习和工作有巨大的帮助,课程设计反映的是一个从理论到实际的应用过程,但是更远一点可以联系到以后的毕业之后从学校步入社会的的过程,对于学习编程的学生,课程设计是相当有意义的,所以有些问题要不断的去实践,变换思维。最终有所收获。 2Linux代码分析为了进一步了解操作系统内核,学习了Linux操作系统的进程同步。主要源代码如下复制进程的页目录页表。int copy_page_tables(unsigned long from,unsigned long to,long size) { unsigned long * from_page_table; unsigned long * to_page_table; unsigned long this_page; unsigned long * from_dir, * to_dir; unsigned long nr; // 源地址和目的地址都需要是4Mb 的倍数。否则出错,死机。if ((from&0x3fffff) || (to&0x3fffff)) panic("copy_page_tables called with wrong alignment"); // 取得源地址和目的地址的目录项(from_dir 和to_dir)。from_dir = (unsigned long *) ((from>>20) & 0xffc); /* _pg_dir = 0 */ to_dir = (unsigned long *) ((to>>20) & 0xffc); // 计算要复制的内存块占用的页表数(也即目录项数)。size = ((unsigned) (size+0x3fffff)) >// 下面开始对每个占用的页表依次进行复制操作。Out of m emory, see freeing */ > 22;for( size-->0 from_dir++,to_dir++) { // 如果目的目录项指定的页表已经存在(P=1),则出错,死机。 if (1 & *to_dir) panic("copy_page_tables: already exist"); // 如果此源目录项未被使用,则不用复制对应页表,跳过。if (!(1 & *from_dir)) continue; // 取当前源目录项中页表的地址from_page_table。from_page_table = (unsigned long *) (0xfffff000 & *from_dir); // 为目的页表取一页空闲内存,如果返回是0 则说明没有申请到空闲内存页面。返回值=-1,退出。if (!(to_page_table = (unsigned long *) get_free_page())) return -1; /* Out of memory, see freeing */// 设置目的目录项信息7 是标志信息,表示(Usr, R/W, Present)。*to_dir = ((unsigned long) to_page_table) | 7; // 针对当前处理的页表,设置需复制的页面数。如果是在内核空间,则仅需复制160 页,否则需要// 复制1 个页表中的所有1024 页面nr = (from==0)?0xA0:1024; // 对于当前页表,开始复制指定数目nr 个内存页面。for ( nr-- > 0 from_page_table++,to_page_table++) { this_page = *from_page_table; // 取源页表项内容。if (!(1 & this_page)) // 如果当前源页面没有使用,则不用复制。continue; // 复位页表项中R/W 标志置0)。(如果U/S位是0,则R/W 就没有作用。如果U/S 是1,而R/W 是0,// 那么运行在用户层的代码就只能读页面。如果U/S 和R/W 都置位,则就有写的权限。) this_page &= ~2; *to_page_table = this_page; // 将该页表项复制到目的页表中。// 如果该页表项所指页面的地址在1M 以上,则需要设置内存页面映射数组mem_map[],于是计算// 页面号,并以它为索引在页面映射数组相应项中增加引用次数。if (this_page > LOW_MEM) *from_page_table = this_page; //令源页表项也只读[??]。this_page -= LOW_MEM; this_page >>= 12; mem_map[this_page]++; } } } invalidate(); // 刷新页变换高速缓冲。return 0; 窗体顶端2.1功能说明这一段程序的主要功能为:(1)复制进程的页目录页表;2.2接口说明本程序的输入参数为:unsigned long from,unsigned long to,long size输出结果:为将进程的页目录页表复制:2.3局部数据结构本程序共有5个局部变量及数据结构,其类型定义及语义如下:unsignedlong*from_page_table;//记录复制文件的位置unsignedlong*to_page_table;//目标文件位置unsignedlongthis_page;//页目录unsignedlong*from_dir,*to_dir;/页表unsignedlongnr;记录页表页面数2.4流程图本程序的流程图如图2所示 图2 程序流程图2.5以实例说明运行过程例如,当有多个进程到达,P表示生产者进程,C表示消费者进程,到达序列为PPPCCPP时,根据分析,运行结果应为:例如,系统需要交换页面时,需要对页面复制,根据分析,运行结果应为:交换成功。返回值为零 实际运行结果如下: 返回值为零,页面已交换 。。。实际运行结果如下:
{if(now-cidao[i]<=(cidao[r]-now))
Sum=prints(cidao,now,m,i,r);
Elsesum=printl(cidao,now,m,i,r)
1.3流程图
1.4实现技术
为实现上述设计,采用C++语言,VS2008开发环境。
具体采用的技术如下:
(1)数组的寻找及其下表的寻找与遍历
(2)数组的排序
实现步骤如下:
(1)根据移动方向,针对数组内值进行磁道移动
(2)对值与值之间进行相见取出磁道移动距离并且进行相干的计算
运行结果如下:
1.5设计结论和心得
通过课程设计得到如下结论:
(1)磁盘,是一种很重要也很常用的外设,其分配也有一定的分配策略。
在操作系统中,作业对磁盘的请求常常要排队,由此需要一些高效率的磁盘分配策略算法。
(2)最短寻道时间优先算法优先选择距离当前磁头位置最近的作业磁道请求,可以使得每次寻道时所用的时间都最短,但不能保证平均周转时间及带权周转时间最短;
有如下几点心得体会:
(1)此次课程设计,是我对磁盘调度算法和原理有了更深刻的理解,对于理论在实践中的应用也有了一定的了解。
(2)对于我以后的学习和工作有巨大的帮助,课程设计反映的是一个从理论到实际的应用过程,但是更远一点可以联系到以后的毕业之后从学校步入社会的的过程,对于学习编程的学生,课程设计是相当有意义的,所以有些问题要不断的去实践,变换思维。
最终有所收获。
2Linux代码分析
为了进一步了解操作系统内核,学习了Linux操作系统的进程同步。
主要源代码如下
复制进程的页目录页表。
int copy_page_tables(unsigned long from,unsigned long to,long size)
{ unsigned long * from_page_table;
unsigned long * to_page_table;
unsigned long this_page;
unsigned long * from_dir, * to_dir;
unsigned long nr;
// 源地址和目的地址都需要是4Mb 的倍数。
否则出错,死机。
if ((from&0x3fffff) || (to&0x3fffff))
panic("copy_page_tables called with wrong alignment");
// 取得源地址和目的地址的目录项(from_dir 和to_dir)。
from_dir = (unsigned long *) ((from>>20) & 0xffc);
/* _pg_dir = 0 */
to_dir = (unsigned long *) ((to>>20) & 0xffc);
// 计算要复制的内存块占用的页表数(也即目录项数)。
size = ((unsigned) (size+0x3fffff)) >//
下面开始对每个占用的页表依次进行复制操作。
Out of m emory, see freeing */ > 22;
for( size-->0 from_dir++,to_dir++) {
// 如果目的目录项指定的页表已经存在(P=1),则出错,死机。
if (1 & *to_dir)
panic("copy_page_tables:
already exist");
// 如果此源目录项未被使用,则不用复制对应页表,跳过。
if (!
(1 & *from_dir))
continue;
// 取当前源目录项中页表的地址from_page_table。
from_page_table = (unsigned long *) (0xfffff000 & *from_dir);
// 为目的页表取一页空闲内存,如果返回是0 则说明没有申请到空闲内存页面。
返回值=-1,退出。
(to_page_table = (unsigned long *) get_free_page()))
return -1; /* Out of memory, see freeing */
// 设置目的目录项信息7 是标志信息,表示(Usr, R/W, Present)。
*to_dir = ((unsigned long) to_page_table) | 7; //
针对当前处理的页表,设置需复制的页面数。
如果是在内核空间,则仅需复制160
页,否则需要// 复制1 个页表中的所有1024 页面nr = (from==0)?
0xA0:
1024; // 对于当前页表,开始复制指定数目nr 个内存页面。
for ( nr-- > 0 from_page_table++,to_page_table++) {
this_page = *from_page_table; // 取源页表项内容。
(1 & this_page)) // 如果当前源页面没有使用,则不用复制。
continue; // 复位页表项中R/W 标志置0)。
(如果U/S位是0,则R/W 就没有作用。
如果U/S 是1,而R/W 是0,// 那么运行在用户层的代码就只能读页面。
如果U/S 和R/W 都置位,则就有写的权限。
)
this_page &= ~2;
*to_page_table = this_page; // 将该页表项复制到目的页表中。
// 如果该页表项所指页面的地址在1M 以上,则需要设置内存页面映射数组mem_map[],于是计算// 页面号,并以它为索引在页面映射数组相应项中增加引用次数。
if (this_page > LOW_MEM)
*from_page_table = this_page; //令源页表项也只读[?
?
]。
this_page -= LOW_MEM; this_page >>= 12;
mem_map
[this_page]++; }
invalidate(); // 刷新页变换高速缓冲。
return 0;
窗体顶端
2.1功能说明
这一段程序的主要功能为:
(1)复制进程的页目录页表;
2.2接口说明
本程序的输入参数为:
unsigned long from,unsigned long to,long size
输出结果:
为将进程的页目录页表复制:
2.3局部数据结构
本程序共有5个局部变量及数据结构,其类型定义及语义如下:
unsignedlong*from_page_table;//记录复制文件的位置
unsignedlong*to_page_table;//目标文件位置
unsignedlongthis_page;//页目录
unsignedlong*from_dir,*to_dir;/页表
unsignedlongnr;记录页表页面数
2.4流程图
本程序的流程图如图2所示
图2 程序流程图
2.5以实例说明运行过程
例如,当有多个进程到达,P表示生产者进程,C表示消费者进程,到达序列为PPPCCPP时,根据分析,运行结果应为
:
例如,系统需要交换页面时,需要对页面复制,根据分析,运行结果应为:
交换成功。
返回值为零
实际运行结果如下:
返回值为零,页面已交换
。
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1