1. 程式人生 > >利用單向迴圈連結串列結構實現如下記憶體頁置換策略CLOCK Algorithm

利用單向迴圈連結串列結構實現如下記憶體頁置換策略CLOCK Algorithm

利用單向迴圈連結串列結構實現如下記憶體頁置換策略CLOCK Algorithm:

假設緩衝池有6個緩衝頁,以單向迴圈連結串列結構組織,結構如下圖所示。緩衝池初始狀態:所有緩衝頁可用,指標P指向下一個即將被分配的緩衝頁。緩衝池包含的緩衝頁數作為程式執行引數設定,該引數的有效設定範圍為[5, 10]。

1

2

3

4

5

6

生成一組隨機物理頁訪問序列,頁編號範圍是0到19,頁面訪問序列長度作為程式執行引數設定。如:9, 1, 10, 1, 9, 18, 7, 7, 12, 17為一個長度為10的物理頁訪問序列。

每一次物理頁訪問,若該頁已經在緩衝池中,則顯示Hit並將該頁對應的緩衝頁狀態更改為R= 1;若該頁不在緩衝池中,則分配一個緩衝頁並將對應緩衝頁的狀態設為R=0;

當需要分配一個緩衝頁給當前訪問的物理頁時:若指標P指向的緩衝頁狀態為R=1,表示該頁剛剛被訪問過應該繼續保留在緩衝池中,因此將該頁的狀態更改為R=0,並使P指向下一個緩衝頁;若指標P指向的緩衝頁狀態為R=0,表明該頁已經有較長時間沒有被訪問,可以將該緩衝頁分配給當前訪問的物理頁。

Link.h

#pragma once

template<typename E> class Link {

public

:

int r = 0;

E element;

Link *next;

Link(const E& elemval, Link* nextval = NULL)

{

element = elemval; next = nextval;

}

Link(Link* nextval = NULL) {

next = nextval;

}

};

LLink.h

#pragma once

template <typename E> class LList {

private:

Link<E>* head;

Link<E

>* tail;

Link<E>* curr;

int cnt;

void init() {

curr = tail = head = new Link<E>;

int cnt = 0;

}

public:

LList()  //建構函式

{

init();

}

void print() const             //輸出

{

Link<E>* temp = head; //遍歷

cout << temp->next->element<<" ";

temp = temp->next;

while (temp->next != head->next)

{

cout << temp->next->element << " ";

temp = temp->next;     //下一個結點

}

cout << endl;

}

void clear()

{

removeall();

init();

}

void insert(const E& it) {

curr->next = new Link<E>(it, curr->next);

if (tail == curr)

tail = curr->next;

cnt++;

}

void append(const E& it) {

tail = tail->next = new Link<E>(it, head->next);

cnt++;

}

E remove() {

Assert(curr->next != NULL, "No element");    

E it = curr->next->element;

Link<E>* ltemp = curr->next;

if (tail == curr->next)

{

tail = curr;

}

curr->next = curr->next->next;

delete ltemp;

cnt--;

return it;

}

void moveToStart() {

curr = head;

}

void moveToEnd() {

curr = tail;

}

void prev() {

if (curr == head)

{

return;

}

Link<E>*temp = head;

while (temp->next != curr) {

temp = temp->next;

}

curr = temp;

}

void next() {              //迴圈連結串列

curr = curr->next;

}

int length() const {

return cnt;

}

int currPos() const {

Link<E>* temp = head;

int i;

for (i = 0; curr != temp; i++)

{

temp = temp->next;

}

return i;

}

void moveToPos(int pos) {

Assert((pos >= 0) && (pos <= cnt), "超出範圍了!");

curr = head;

for (int i = 0; i < pos; i++)

{

curr = curr->next;

}

}

const E& getValue() const {

return curr->next->element;

}

const int& getR() const {

return curr->next->r;

}

void changeE(const E& it) {

curr->next->element = it;

}

void changeR(const int it) {

curr->next->r = it;

}

};

Clock.cpp

#include<iostream>

#include<time.h>

#include"Link.h"

#include"LLink.h"

using namespace std;

#define random(x) (rand()%x)

void genSeq(int seq_len, int a[]) {

srand((int)time(0));

for (int i = 0; i < seq_len; i++)

{

a[i] = random(19);

}

}

void allocBuff(LList<int> temp, int a) {

while (temp.getR() == 1)

{

temp.changeR(0);

temp.next();

}

temp.changeE(a);

}

void visitPage(int buf_len, LList<int> temp, int a) {

for (int i = 0; i < buf_len; i++)

{

if (temp.getValue() == a)

{

cout << "Hit";

temp.changeR(1);

return;

}

temp.next();

}

allocBuff(temp,a);

}

void ClockPR(int buf_len, int seq_len, int a[]) {

LList<int> clock;

for (int i = 0; i < buf_len; i++)

{

clock.append(20);       //20代表空

}

for (int i = 0; i < seq_len; i++)

{

visitPage(buf_len, clock, a[i]);

cout << "第" << i + 1 << "次訪問:";

clock.print();

clock.next();

}

}

int main() {

cout << "輸入頁面訪問序列長度:" << endl;

int seq_len;

cin >> seq_len;

int *a = new int[seq_len];

genSeq(seq_len, a);

cout << "輸入範圍為[5,10]的快取頁數:" << endl;

int buf_len;

cin >> buf_len;

while (buf_len < 5 || buf_len>10) {

cout << "範圍為[5,10]哦!" << endl;

cin >> buf_len;

}

ClockPR(buf_len, seq_len,a);

system("pause");

}