实验报告三
实验名称:理解线程和请求分页存储管理设计日期:2011/5/25 班级:学号:姓名:
一、实验目的:
1. 理解当操作系统引入线程的概念后,进程是操作系统独立分配资源的单位,
线程成为系统调度的单位,也是系统并发运行的独立单位。
同一个进程中的
各个线程共享进程的地址空间。
2. 模拟存储管理常用的请求分页存储管理技术,通过本实验使学生更加深入的
理解虚拟内存的思想和主要的页面淘汰算法。
二、实验内容:
1. (1)编写一个程序,在其main()函数中创建一个(或多个)线程,观察该
线程是如何与主线程并发运行的。
输出每次操作后的结果;
(2)在main()函数外定义一个变量int shared(全局变量),在main()中创建
一个线程,在main()中和新线程shared 进行循环加/减操作,观察该变量的变化;
(3)修改程序把int shared 变量定义到main()函数之内,重复第(2)步操作,观察该变量的变化。
(4)编写一个程序,在其main()函数中创建至少两个线程,在这些线程中分别说明(定义)名称相同的整型变量(例如,int x;),分别在各个线程中修改这些变量,试观察这些变量值的变化。
2. (1) 通过随机数产生一个指令行列,共320条指令,指令中的地址按下述原则
生成:50%的指令是顺序执行;25%的指令均匀分布在前地址部分;25%的指令均匀分布在后地址部分。
(2) 具体实验办法是:在[0,319]之间选一起始点M;顺序执行一条指令,即
第M+1条;向前地址[0,M-1]中执行一条指令M;顺序执行一条指令,即第
M+1条;向后地址[M+2,319]中执行一条指令M。
如此继续,直至产生320条指令。
使用产生随机数的函数之前,首先要初始化设置RAN()产生序列的开
始点,SRAND(400);然后计算随机数,产生指令序列。
例如:
a[0]=1.0*rand()/32767*319+1;
a[1]=a[0]+1;
a[2]=1.0*rand()/32767*(a[1]-1)+1;
a[3]=a[2]+1;
a[4]=319-1.0*rand()/32767*(a[3]-1);其中rand()和srand()为Linux操作系统提供
指令序列。
(3) 将指令序列变换成页面地址流:假设,页面大小为1KB;用户实存容量(内
存区容量)为4页或32页;用户虚存容量(逻辑地址空间容量)为32KB;用
户虚存容量32KB,每1KB中放10条指令,共320条指令序列,按其地址0~9在
0页,10~19在1页,…….,310~319在31页。
(4) 使用不同的页面调度算法处理缺页中断,并计算不同实存容量下的命中
率:先进先出(FIFO)算法;最近最少使用(LRU)算法;命中率的算法为:
命中率= 1 - (缺页中断次数/页地址流长度)。
本实验中,页地址流长度为
320,缺页中断次数为每次访问相应指令时,该指令所对应的页不在内存的次
数。
三、项目要求及分析:
1.在同一进程中的各个线程,都可以共享该进程所拥有的资源,这表现在:所有线程
都具有相同的地址空间(进程的地址空间)。
此外我们应该还要用控制语句,控制线程的同步执行。
2. 这个实验是要求我们采用算法模拟分页存储管理技术的FIFO和LRU算法。
所以我们
应该先生成地址序列,有了地址序列,我们要找到它所在的虚页,然后通过查找实页,再判断下一步动作。
假如要访问的虚页不在内存中,不命中,我们要替换实页内容。
根据FIFO算法,直接替换最早进入内存中的那一页就可以了。
所以可以设立一个循环指针,记录那个最早进入内存中的那页。
而对于LRU算法,我们要替换是到现在为止最长时间没被访问的页,在这里我们可以用一个队列来表示内存。
把最久没使用的页放在队头,然后替换进去的页放在队尾就可以了。
假如要访问的虚页在内存中,明显是命中。
对于FIFO算法,不处理,而对于LRU算法,我们还要把他的权值置0。
四、具体实现:
1.实验程序:1.1
结果:
1.2
结果:1.3
结果:1.4
结果:
2. 源程序:
#include "stdio.h"
#include "stdlib.h"
#include "time.h"
#define MAXPAGE 4
int page[MAXPAGE]={-1,-1,-1,-1}; int num1,num2,num3;
int exist(int n)
{
int i;
for(i=0;i<MAXPAGE;i++)
{
if(n==page[i])
}
return -1;
}
void main()
{
int i,j,t,k,temp;
int a[320];
int key=0;
int b[4]={0};
srand(time(NULL));
a[0]=1.0*rand()/RAND_MAX*319+1;
for(i=1;i<320;i++)
{
if(i%4==1)
a[i]=a[i-1]+1;
if(i%4==2)
a[i]=1.0*rand()/RAND_MAX*(a[i-1]-1)+1;
if(i%4==3)
a[i]=a[i-1]+1;
if(i%4==0)
a[i]=319-1.0*rand()/RAND_MAX*(a[i-1]-1);
}
for(i=0;i<320;i++)
{
printf("hello,the current page float is %d %d %d %d",page[0],page[1],page[2],page[3]);
//如果命中的话,返回命中的页数,并且置命中页数的权值为,其余加一。
if((k=exist(a[i]/10))!=-1)
{
b[k]=0;
for(j=0;j<4;j++)
{
if(j!=k)
++b[j];
}
printf("hello,we hit it,the page float is %d %d %d %d \n",page[0],page[1],page[2],page[3]);
continue;
}
else
{
//如果没有命中,我们就替换最少使用的,页数置,其余的加一
temp=-10;
for(j=0;j<4;j++)
{
if(b[j]>temp)
temp=b[j];
key=j;
}
}
page[key]=a[i]/10;
b[key]=0;
for(j=0;j<4;j++)
{
if(j!=key)
++b[j];
}
key=0;
++num2;
printf("hello,we miss it,the page float is %d %d %d %d\n",page[0],page[1],page[2],page[3]);
}
}
printf("hello,the hit rate is %.2f%%",(1.0-(double)num2/320)*100);
printf("\n");
}
实验结果:
五、实验总结:
1.第一道涉及线程的题编译时总是发生错误,原来编译这类程序在原有的编译语言后要加上-pthread.
2.第二个分页算法我们在系统结构课已经做过这个实验,所以有了一定的了解,加上一点修改就能够使用了。
所以没太花功夫。