【操作系統】實驗四 主存空間的分配和回收


實驗四主存空間的分配和回收

14商業軟件工程專業   姓名:陳彥生  學號:201406114124

一、目的和要求

1. 實驗目的

用高級語言完成一個主存空間的分配和回收程序,以加深對動態分區分配方式及其算法的理解。

2.實驗要求

采用連續分配方式之動態分區分配存儲管理,使用首次適應算法、循環首次適應算法、最佳適應算法和最壞適應算法4種算法完成設計(任選兩種算法)。

(1)設計一個作業申請隊列以及作業完成后的釋放順序,實現主存的分配和回收。采用分區說明表進行。

(2)或在程序運行過程,由用戶指定申請與釋放。

(3)設計一個空閑區說明表,以保存某時刻主存空間占用情況。把空閑區說明表的變化情況以及各作業的申請、釋放情況顯示。

二、實驗內容

編寫並調試一個模擬的內存分配與回收程序,使用首次適應算法、循環首次適應算法對內存空間的分配與回收。

三、實驗方法、步驟及結果測試

1.    源程序名:a.cpp

可執行程序名:a.exe

2.    原理分析

(1)編寫該程序首先要給定一個一定空間大小的內存,即申請空閑區空間最大值,並且要定義空間的各分區的作業標號、分區起始地址、分區長度,單位為字節、分區表的狀態位、前向指針、后向指針、已分配分區表、空閑分區等。

(2)通過定義空間分區后,還要定義空間分區鏈表並對其進行初始化,對空閑分區和已分配分區進行鏈表訪問,對於空閑分區可以分配給新進來的進程使用,對於已分配的分區,則等進程執行結束后在回收空間,恢復空閑區。通過鏈表的訪問實現整個空間分區的分配與回收。

3.      主要程序段及其解釋:

#include<stdio.h>
#include<stdlib.h>
#include <conio.h>
#define nil -1
#define NULL 0
#define maxisize 600    //用戶的空閑區空間最大值
#define minisize 4     
#define getspace(type) (type*)malloc(sizeof(type)) //分配空間
struct table{
    char job;                 //作業標號
    float address;            //分區起始地址
    float length;             //分區長度,單位為字節
    int flag;                 //分區表的標志
    struct table *FRlink;     //前向指針
    struct table *RElink;    //后向指針
}*free_table=NULL,*place;   //已分配分區表,空閑分區表
typedef struct table FRtable;
//空間分區鏈表初始化
FRtable *init(FRtable *tb)
{
    tb->FRlink=NULL;
    tb->job=nil;
    tb->address=1064;
    tb->length=1664;
    tb->flag=0;
    tb->RElink=NULL;
    return tb;
}
//主存分配函數,為作業job分配大小為xk的分區空間
void allocate(char job,float xk,int choice)
{
    FRtable *tb,*link;
    int k=0;
    float temp=600;
    if (free_table->FRlink==NULL&&free_table->RElink==NULL)
    {//給首個作業分配空間,改寫分區鏈表
        free_table->job=job;
        free_table->length=xk;
        free_table->flag=1;
        if (xk<maxisize)
        {
            tb=getspace(FRtable);
            free_table->RElink=tb;
            tb->FRlink=free_table;
            tb->job=nil;
            tb->address=1064+xk;
            tb->length=maxisize-xk;
            tb->flag=0;
        }
        if (choice==2)
        {//鏈接成循環鏈表
            free_table->FRlink=tb;
            tb->RElink=free_table;
            place=tb;
        }
        else
        {
            free_table->FRlink=NULL;
            if (xk<maxisize) tb->RElink=NULL;
        }
        k=1;
    }
    else
    {
        if (2==choice) tb=place;//采用CFF時將ta定位到上次找到的合適空間分區的下個空間分區
        else tb=free_table;
        while(tb!=NULL)
        {
            if (3==choice)
            {
                while(tb!=NULL)
                {
                    if (tb->length>=xk&&tb->flag==0)
                        if (tb->length<temp)
                            {place=tb;temp=tb->length;}   //選擇最適合空間
                    tb=tb->RElink;
                }
                tb=place;
            }
            if (tb->length>=xk&&tb->flag==0)
                if (tb->length-xk<=minisize)
                {//當搜索到的空間大小<=xk+minisize時,將空間全部分配給作業
                    tb->job=job;
                    tb->flag=1;
                    place=tb->RElink;
                    k=1;
                    break;
                }
                else
                {//當搜索到的空間大小>xk+minisize時,將空間划分,再分配給作業
                    link=getspace(FRtable);
                    link->length=tb->length-xk;
                    tb->job=job;
                    tb->length=xk;
                    tb->flag=1;
                    link->RElink=tb->RElink;
                    if (NULL!=tb->RElink) tb->RElink->FRlink=link;
                    tb->RElink=link;
                    link->FRlink=tb;
                    link->job=nil;
                    link->address=tb->address+xk;
                    link->flag=0;
                    place=link;
                    k=1;
                    break;
                }
            tb=tb->RElink;
        }
    }
    if (0==k)
    {//未尋找到合適的空間分區,返回
        printf(">>空間申請失敗! \n");
        return;
    }
}

//主存回收函數,回收作業job所占用的分區空間
void reclaim(char job,int choice)
{
    int bool1=0,bool2=0;
    FRtable *tb,*link;
    tb=free_table;
    if (2==choice) link=tb;
    else link=NULL;
    do
    {
        if (job==tb->job&&1==tb->flag) break;
        tb=tb->RElink;
        if (tb==link)
        {
            printf("\n>>抱歉,不存在作業%c! \n",job);
            return;
        }
    }while(tb!=link);
    bool1=(NULL==tb->FRlink||tb->FRlink==tb->RElink)? 1:tb->FRlink->flag;
    bool2=(NULL==tb->RElink||tb->FRlink==tb->RElink)? 1:tb->RElink->flag;
    if (bool1&&bool2)
    {
        tb->job=nil;
        tb->flag=0;
    }
    else if ((NULL==tb->FRlink||1==tb->FRlink->flag)&&0==tb->RElink->flag)
    {
        link=tb->RElink;
        tb->job=nil;
        tb->length+=link->length;
        tb->flag=0;
        tb->RElink=link->RElink;
        if (NULL!=link->RElink) link->RElink->FRlink=tb;
        free(link);
    }
    else if (0==tb->FRlink->flag&&1==tb->RElink->flag)
    {
        link=tb->FRlink;
        link->length+=tb->length;
        link->RElink=tb->RElink;
        tb->RElink->FRlink=link;
        if (free_table==tb) free_table=link;
        free(tb);
    }
    else if (0==tb->FRlink->flag&&0==tb->RElink->flag)
    {
        link=tb->FRlink;
        link->length=link->length+tb->length+tb->RElink->length;
        link->RElink=tb->RElink->RElink;
        if (NULL!=tb->RElink->RElink) tb->RElink->RElink->FRlink=link;
        if (free_table==tb) free_table=link;
        free(tb);
        free(tb->RElink);
    }
}
//顯示空間分區鏈表
void display(FRtable *tb,int choice)
{
//    clrscr();
    FRtable *temp;
    if (2==choice) temp=tb;
    else temp=NULL;
    printf("\n\t標號\t起始地址\t分區大小(KB)\t    標志\n");
    printf("\n\t sys\t 1024.00\t 40.00\t\t     1\n");
    do
    {
        printf("\n\t %c\t %.2f\t %.2f\t\t     %d\n",tb->job,tb->address,tb->length,tb->flag);
        tb=tb->RElink;
    }while(temp!=tb);
}
//主函數
int main()
{
    int i,a,choice;
    float xk;
    char job;
    FRtable *ta=getspace(FRtable);
    free_table=init(ta);
    do{
        printf("\n 分區分配算法:\n\t0 - 退出(Exit)\n\t1 - 首次適應算法(FF)\n\t2 - 循環首次適應算法(CFF)\n \n");
        printf(">>請選擇相應的算法:");
        scanf("%d",&choice);
        if (0==choice) exit(0);
    }while(0>choice&&2<choice);
    while(1)
    {
        printf("\n    菜單:\n\t0 - 退出(Exit)\n\t1 - 申請空間(Allocation)\n\t2 - 回收空間(Reclaim) \n");
        printf(">>請選擇你的操作:");
        scanf("%d",&a);
        switch(a)
        {
            //a=0,程序結束
            case 0:exit(0);
            //a=1,分配主存空間
            case 1:printf(">>請輸入作業標號和所需要申請的空間:");
                    scanf("%*c%c%f",&job,&xk);
                    allocate(job,xk,choice);
                    display(free_table,choice);
                    break;
            //a=2,回收主存空間
            case 2:printf(">>請輸入你想回收的作業的相應標號:");
                    scanf("%*c%c",&job);
                    reclaim(job,choice);
                    display(free_table,choice);
                    break;
            default:printf(">>ERROR:No thie choose! \n");
        }
    }
}

4.運行結果

如上圖所示,當輸入需要申請的空間和標號后,空閑分區會分配相應的空間大小,當輸入回收的標號時,內存會回收相應大小的空間。根據實驗結果顯示,實驗已達到預期效果。

實驗總結

(1)本次實驗是有關內存空間分配的算法的實現,實驗內容相對之前的進程調度稍微簡潔些,但是基本實現的數據結構的鏈表算法是一樣的,還是需要通過申請空間,定義分區大小,然后通過鏈表對各空閑分區進行相應的內存分配。

(2)雖然對實驗步驟比較清晰,對首次適應算法、循環首次適應算法的知識理解得比較好,但是在對如何通過這些算法去實現這個內存分配的實驗,還是遇到很多困難,比如鏈表初始化與訪問的算法基礎掌握得不好,還有一些基本的C語言的語法結構掌握不熟練,而且對算法與與程序之間的思維不清晰,導致在寫程序中出現較多問題,然后通過查找課本,上網搜尋資料,詢問同學進行幫助解答,最后得到基本的實驗程序。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM