【大三操作系统实验】 请求页式管理中的置换算法

2020-12-29 14:22:00 浏览数 (1)

参考链接: Python中的置换和组合

(1)FIFO算法总是选择在内存驻留时间最长的一页将其淘汰。FIFO算法认为调入内存的页不再被可能性要比其他页大,因而选择最先调入内存的页换出。 

(2)LRU算法基本思想:当需要淘汰某一页时,选择离当前时间最近的一段时间内最久没有使用过的页先淘汰。 

(3)OPT算法基本思想:在访问串中将来再也不出现的或是在离当前最远的位置上出现的页。 

主要算法实现代码部分在Onqueding() 

   Code:

 // 置换算法Dlg.cpp : implementation file     //       #include "stdafx.h"    #include "置换算法.h"    #include "置换算法Dlg.h"       #ifdef _DEBUG    #define new DEBUG_NEW    #undef THIS_FILE    static char THIS_FILE[] = __FILE__;    #endif       /    // CAboutDlg dialog used for App About            CRect rectSmall;  //收缩          CRect rectLarge;  //扩展         CRect rectrang_1;  //边缘                bool flag=true;        int i,j,k,m;            int visit[19];   //访问数组        int *count;  //停留标记        int *mem;  //内存分配页    int FIFO(int *count_0,int num);    int OPT(int *count_0,int i,int num,int *vis);    class CAboutDlg : public CDialog    {    public:        CAboutDlg();       // Dialog Data        //{{AFX_DATA(CAboutDlg)         enum { IDD = IDD_ABOUTBOX };        //}}AFX_DATA           // ClassWizard generated virtual function overrides        //{{AFX_VIRTUAL(CAboutDlg)        protected:        virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support        //}}AFX_VIRTUAL       // Implementation    protected:        //{{AFX_MSG(CAboutDlg)         //}}AFX_MSG        DECLARE_MESSAGE_MAP()    };       CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)    {        //{{AFX_DATA_INIT(CAboutDlg)        //}}AFX_DATA_INIT    }       void CAboutDlg::DoDataExchange(CDataExchange* pDX)    {        CDialog::DoDataExchange(pDX);        //{{AFX_DATA_MAP(CAboutDlg)        //}}AFX_DATA_MAP    }       BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)        //{{AFX_MSG_MAP(CAboutDlg)            // No message handlers        //}}AFX_MSG_MAP    END_MESSAGE_MAP()       /    // CMyDlg dialog       CMyDlg::CMyDlg(CWnd* pParent /*=NULL*/)        : CDialog(CMyDlg::IDD, pParent)    {        //{{AFX_DATA_INIT(CMyDlg)         m_suanfa = -1;        //}}AFX_DATA_INIT        // Note that LoadIcon does not require a subsequent DestroyIcon in Win32        m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);    }       void CMyDlg::DoDataExchange(CDataExchange* pDX)    {        CDialog::DoDataExchange(pDX);        //{{AFX_DATA_MAP(CMyDlg)         DDX_Control(pDX, IDC_rang, m_rang);        DDX_Radio(pDX, IDC_RADIO1, m_suanfa);        //}}AFX_DATA_MAP    }       BEGIN_MESSAGE_MAP(CMyDlg, CDialog)        //{{AFX_MSG_MAP(CMyDlg)        ON_WM_SYSCOMMAND()        ON_WM_PAINT()        ON_WM_QUERYDRAGICON()        ON_WM_MOUSEMOVE()        ON_BN_CLICKED(IDC_queding, Onqueding)        //}}AFX_MSG_MAP    END_MESSAGE_MAP()       /    // CMyDlg message handlers       BOOL CMyDlg::OnInitDialog()    {        CDialog::OnInitDialog();           // Add "About..." menu item to system menu.           // IDM_ABOUTBOX must be in the system command range.        ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);        ASSERT(IDM_ABOUTBOX < 0xF000);           CMenu* pSysMenu = GetSystemMenu(FALSE);        if (pSysMenu != NULL)        {            CString strAboutMenu;            strAboutMenu.LoadString(IDS_ABOUTBOX);            if (!strAboutMenu.IsEmpty())            {                pSysMenu->AppendMenu(MF_SEPARATOR);                pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);            }        }           // Set the icon for this dialog.  The framework does this automatically        //  when the application's main window is not a dialog        SetIcon(m_hIcon, TRUE);         // Set big icon        SetIcon(m_hIcon, FALSE);        // Set small icon                // TODO: Add extra initialization here        /*       CRect rect,rect_1;         m_rang.GetWindowRect(&rect);       GetWindowRect(&rect_1);       rect_1.right=rect.right 2;       SetWindowPos(NULL,0,0,rect_1.Width(),rect_1.Height(),               SWP_NOMOVE | SWP_NOZORDER);               */       m_rang.GetWindowRect(&rectrang_1);        GetWindowRect(&rectLarge);        rectSmall.top=rectLarge.top;        rectSmall.left=rectLarge.left;        rectSmall.right=rectrang_1.right;        rectSmall.bottom=rectLarge.bottom;        //默认为FIFO算法        m_suanfa=0;        UpdateData(FALSE);        return TRUE;  // return TRUE  unless you set the focus to a control    }       void CMyDlg::OnSysCommand(UINT nID, LPARAM lParam)    {        if ((nID & 0xFFF0) == IDM_ABOUTBOX)        {            CAboutDlg dlgAbout;            dlgAbout.DoModal();        }        else       {            CDialog::OnSysCommand(nID, lParam);        }    }       // If you add a minimize button to your dialog, you will need the code below    //  to draw the icon.  For MFC applications using the document/view model,    //  this is automatically done for you by the framework.       void CMyDlg::OnPaint()     {        if (IsIconic())        {            CPaintDC dc(this); // device context for painting               SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);               // Center icon in client rectangle            int cxIcon = GetSystemMetrics(SM_CXICON);            int cyIcon = GetSystemMetrics(SM_CYICON);            CRect rect;            GetClientRect(&rect);            int x = (rect.Width() - cxIcon 1) / 2;            int y = (rect.Height() - cyIcon 1) / 2;               // Draw the icon             dc.DrawIcon(x, y, m_hIcon);        }        else       {            CDialog::OnPaint();        }        CDC *pDC = GetWindowDC();   //获取窗口DC         CDC *memDC  =   new   CDC;   //定义兼容DC    //  if(flag)    //  {            memDC->CreateCompatibleDC(pDC);        //加载位图        CBitmap pBit;        pBit.LoadBitmap(IDB_BITMAP1);        CBitmap *pOldBit;        //选位图进memDC        pOldBit=(CBitmap *)memDC->SelectObject(&pBit);        CRect rect;        CRect rectrang;        m_rang.GetWindowRect(&rectrang);        GetWindowRect(&rect);        rect.right=rectrang.right;        BITMAP bitmap;        pBit.GetBitmap(&bitmap);        //pDC->BitBlt(0,0,rect.Width(),rect.Height(),memDC,0,0,SRCCOPY);        pDC->StretchBlt(0,0,rect.Width(),rect.Height(),memDC,0,0,bitmap.bmWidth,bitmap.bmHeight,SRCCOPY);        memDC->SelectObject(pOldBit);        pDC->SetBkMode(TRANSPARENT);    //  flag=false;            //  }    }       // The system calls this to obtain the cursor to display while the user drags    //  the minimized window.    HCURSOR CMyDlg::OnQueryDragIcon()    {        return (HCURSOR) m_hIcon;    }       void CMyDlg::OnMouseMove(UINT nFlags, CPoint point)     {        // TODO: Add your message handler code here and/or call default                if(point.x>= rectSmall.right-10)  //扩展        {                        SetWindowPos(NULL,0,0,rectLarge.Width(),rectLarge.Height(),                SWP_NOMOVE |  SWP_NOZORDER);            if(flag)            {            this->Invalidate(FALSE);            flag=false;  //只闪烁一次            }        }        else   //收缩        {            SetWindowPos(NULL,0,0,rectSmall.Width(),rectSmall.Height(),                SWP_NOMOVE |  SWP_NOZORDER);            flag=true;        }        //this->Invalidate(FALSE);        CDialog::OnMouseMove(nFlags, point);    }          void CMyDlg::Onqueding()     {        UpdateData();        CListCtrl *m_list = new CListCtrl();        m_list->Create(WS_CHILD | WS_VISIBLE |LVS_REPORT,CRect(20,20,545,400),this,102);        //改为网状风格        DWORD dwStyle=m_list->GetExtendedStyle();        dwStyle |= LVS_EX_FULLROWSELECT;  //整行高亮所选中的行只适用Report Style        dwStyle |= LVS_EX_GRIDLINES;           //网格线. 只适用Report Style        m_list->SetExtendedStyle(dwStyle );                m_list->SetBkColor(RGB(50,200,50));//绿背景色        m_list->SetTextColor(RGB(0,0,220)); //蓝文本色        m_list->SetTextBkColor(RGB(50,200,50));  //绿文本背景色        m_list->InsertColumn(0,"访问序列",LVCFMT_LEFT,75);                   int m_proc=this->GetDlgItemInt(IDC_COMBO1);  //获取组合框文本        int m_mem=this->GetDlgItemInt(IDC_COMBO2);        int stay;        CString cs;        bool flag1=true;        if(m_mem)  //有值才动态定义        {            mem = new int[m_mem];   //内存分配数组            memset(mem,-1,sizeof(int)*m_mem);  //初始化为-1            count = new int[m_mem];   //标记驻留次数            memset(count,0,sizeof(int)*m_mem);   //初始化为0        }                if(m_proc)        {                   for(j=1;j<19;j )   //初始化列            {                visit[j]=rand()%m_proc;    //访问序列初始化                                cs.Format("%d",visit[j]);                m_list->InsertColumn(j,cs,LVCFMT_LEFT,25);            }        }        for(k=0;k<m_mem;k )    //初始化行,分配页        {            char cha[2];            itoa(k,cha,10);            cs="内存第页";  //汉字双字节,注意            cs.Insert(6,cha);            m_list->InsertItem(k,cs);                    }        if(m_mem &&m_proc)        {            for(i=1;i<19;i )  //列            {                for(k=0;k<m_mem;k ,i )    //行                {                                        for(j=0;j<m_mem;j )   //找出相等的内存页visit[i]与所有行比较                        if(mem[j]==visit[i])   //若相等马上输出所有行                        {                            switch(m_suanfa)                            {                            case 1:   //FIFO变为LRU只需把逗留数组count置为0就可以了                                count[j]=0;   //相同的内存页把逗留次数置0                                break;                            }                            for(m=0;m<m_mem;m )  //输出                            {                                   if(mem[m]!=-1)                                {                                    cs.Format("%d",mem[m]);                                    m_list->SetItemText(m,i,cs);                                    count[m] ;                                                                    }                            }                            k--;                            flag1=false;                            break;//找到相等的先输出所有行,,然后跳出                        }                        ///                         if(flag1)                           {                               switch(m_suanfa)                            {                            case 0: //FIFO                            case 1: //LRU                                if(mem[m_mem-1]!=-1)    //内存页满,开始置换                                {                                    stay=FIFO(count,m_mem);   //谁的逗留时间最长                                                                        mem[stay]=visit[i];   //最长的被置换                                    count[stay]=0;   //逗留次数清零                                }                                else    //内存页还没用完                                {                                    mem[k]=visit[i];                                }                                                                                   break;                            case 2:  //OPT                                if(mem[m_mem-1]!=-1)    //内存页满,开始置换                                {                                    stay=OPT(mem,i,m_mem,visit);   //谁的逗留时间最长                                                                        mem[stay]=visit[i];   //最长的被置换                                }                                else    //内存页还没用完                                {                                    mem[k]=visit[i];                                }                                                                    break;                            }//switch                            for(m=0;m<m_mem;m )  //输出所有行                                    if(mem[m]!=-1)                                    {                                        CString cst;                                        cst.Format("%d",mem[m]);                                        m_list->SetItemText(m,i,cst);                                        count[m] ;  //标记停留次数                                    }                        }                        flag1=true;                ///                         }//for(k                if(k==m_mem) i--;  //有两个i             }//for(i            delete []count;            delete []mem;        }//if        UpdateData(FALSE);    }       int FIFO(int *count_0,int num)    {        int Max=count_0[0];        int Max_stay=0;        for(int n=1;n<num;n ) //找出最大数的下标         if(Max < count_0[n])            {                Max=count_0[n];                Max_stay=n;            }            return Max_stay;    }    int *L;    int OPT(int *temp_mem,int i,int num,int *vis)    {        int Max;        int Max_stay;        int p=i 1;        L = new int[num];        memset(L,0,sizeof(int)*num);  //从0开始        for(int n=0;n<num;n )            for(i=p;i<19;i )  //下一个开始比            if(temp_mem[n]!=vis[i]) L[n] ;            else break;            Max=L[0];            Max_stay=0;            for(int h=0;h<num;h )   //找出最大数的下标            {                            if(Max < L[h])                {                    Max=L[h];                    Max_stay=h;                }            }                delete []L;        return Max_stay;    }

0 人点赞