1、(3)修改程序把shared 变量定义到main()函数之内,重复第(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);然后计算随
2、机数,产生指令序列。例如:a0=1.0*rand()/32767*319+1;a1=a0+1;a2=1.0*rand()/32767*(a1-1)+1;a3=a2+1;a4=319-1.0*rand()/32767*(a3-1);其中rand()和srand()为Linux操作系统提供的函数分别进行初始化和产生随机数,多次重复使用这5条指令,产生以后的指令序列。(3) 将指令序列变换成页面地址流:假设,页面大小为1KB;用户实存容量(内存区容量)为4页或32页;用户虚存容量(逻辑地址空间容量)为32KB;用户虚存容量32KB,每1KB中放10条指令,共320条指令序列,按其地址09在0页,10
3、19在1页,.,310319在31页。(4) 使用不同的页面调度算法处理缺页中断,并计算不同实存容量下的命中率:先进先出(FIFO)算法;最近最少使用(LRU)算法;命中率的算法为:命中率= 1 - (缺页中断次数/页地址流长度)。本实验中,页地址流长度为320,缺页中断次数为每次访问相应指令时,该指令所对应的页不在内存的次数。四、具体实现:4.1 流程图4.2 添加函数的代码1. 理解线程的相关概念【代码使用C+编写】#include pthread.hunistd.husing namespace std;class thread_data_base public: thread_data
4、_base() thread_data_base() virtual void run() = 0;template class thread_data : public thread_data_base thread_data(F _f): f(_f) void run() f();private: F f;class thread static void* _thread_call(void* arg) thread_data_base *base = reinterpret_cast(arg); base-run(); return NULL; static void* _thread_
5、call_self(void* arg) (thread*)arg)- explicit thread(): tid(-1) ret = pthread_create(&tid, NULL, &thread:_thread_call_self, this); template explicit thread( F f ) : tid(-1), _data(new thread_data(f)_thread_call, _data); virtual thread() / pthread_exit(&ret); virtual void run() _data- void join() pthr
6、ead_join(tid, &status); int gettid() return tid; int getReturnValue() return ret; pthread_t tid; int ret; void *status; thread_data_base *_data;int global_count = 0;struct testFunctorvoid operator()(void) while(1) cout global_count+ endl;struct testFunctor2 global_count- int main() testFunctor test;
7、 testFunctor2 test2; thread thr(test); thread thr2(test2); thr.join(); thr2.join(); return 0; #include stdlib.h#define FALSE 0#define INVALID -1#define NUL 0#define total_ins 320#define total_vp 32#define clc_period 50typedef struct int pn, pfn, counter, time;pl_type;pl_type pltotal_vp;typedef struc
8、t pfc_struct int pn,pfn; struct pfc_struct *next;pfc_type;pfc_type pfctotal_vp, *freepf_head, *busypf_head, *busypf_tail;int diseffect, atotal_ins;int pagetotal_ins, offsettotal_ins;void init(int);void FIFO(int);void LRU(int); int S; srand(int)getpid(); S = (int)rand()%390; for(int i=0; inext; plbus
9、ypf_head-pn.pfn = INVALID; freepf_head = busypf_head; freepf_head-next = NUL; busypf_head = p; p = freepf_head-pn = pagei; pl pagei .pfn = freepf_head-pfn; if( busypf_tail=NUL ) busypf_head = busypf_tail = freepf_head; else busypf_tail-next = freepf_head; busypf_tail = freepf_head; freepf_head = p;F
10、IFO: %.6f, 1-(float)diseffect/320);void LRU(int total_pf) int min, minj, i, j, present_time; present_time = 0; min = 32767; for( j=0; jplj.time & plj.pfn != INVALID ) min = plj.time; minj = j; freepf_head = &pfc plminj.pfn ; plminj.pfn = INVALID; plminj.time = -1; pl pagei .time = present_time; free
11、pf_head = freepf_head- else present_time +;LRU:%6.4fvoid init(int total_pf) diseffect = 0; pli.pn = i; pli.pfn = INVALID; pli.counter = 0; pli.time = -1; for( i=1;total_pf; pfci-1.next = &pfci; pfci-1.pfn = i-1; pfctotal_pf-1.next = NUL; pfctotal_pf-1.pfn = total_pf-1;pfc0;五、调试运行结果: (1) (2)六、所遇问题及解决
12、方法: 开始时不知道该如何构造线程,在查看了老师分享的资料之后,开始稍微有些明白了,在后面慢慢的实践过程中,逐步对线程的创建和使用等有了更加深入的了解。在分页存储管理中,不明白指令应如何生成,后来经过与同学的讨论,终于明白了大意,再就是FIFO和LRU分页算法,虽然上课时感觉听的还算可以,可是在实际动手编程时还是有些迷茫,主要还是动手比较少,以后应加强这方面的锻炼。七、实验总结:1. 在理解线程的相关概念的实验中,应注意shared 的全局性和局部性,而且在作为局部变量时,应注意print_thread_id()函数和pthread_create()函数的使用,因为后者的第四个参数是指针型变量,故在传递shared的值时应注意指针的使用。2. 在请求分页存储管理设计实验中,首先应先生成一定数目的指令,然后再构建相应的FIFO和LRU算法,然后分别使用不同的分页算法,比较不同算法的命中率。