操作系统原理与实验——实验十分段存储管理

2024-05-09 14:52

本文主要是介绍操作系统原理与实验——实验十分段存储管理,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

实验指南

运行环境:

Dev c++

算法思想:

本实验是模拟分段存储管理,系统需要建立两张分区表,分别是已分配和未分配分区表,首先根据装入作业的大小判断是否小于空闲分区的总容量,若满足,则对该作业继续进行分段,每输入一个分段大小就在空闲分区中找到第一个没有使用且足够大的分区,若找到将该分区标记为该作业名和对应的分段号,修改已分配和未分配分区表,并打印内存分配信息。对已分配分区的回收,首先输入要回收的作业名,找到该作业的每一段所在的分区,修改已分配分区表,未分配分区表(根据是否存在上下邻),打印回收成功后内存分配信息。

关键数据结构定义:

//内存结构体

typedef struct memory_node

{

    int size; //内存大小

    int address; //内存始址

} memoryNode;

memoryNode memory;

//分区结构体

typedef struct link_node

{

    int id;//分区号

    int size; //分区长度

    int address; //分区始址

    char flag[20]; //分区状态,空闲或者占用作业名

    struct link_node* next;

} node;

//段表

typedef struct segment_node

{

    int a[10][10];

    struct segment_node *next;

} segmentNode;

程序框架:

//函数名 :initMemory  参数:无

node* initMemory()

{

  //函数功能:初始化内存空间

}

//函数名:operation 参数:node* head

int operation(node *head)

{

//函数功能:打印操作菜单,选择需要进行的操作,输入1进行内存 分配,输入2进  行内存去配,输入0退出

}

//函数名:allocate 参数:node* head

void allocate(node *head)

{

//函数名:输入作业名和大小,默认采用最先分配

}

//函数名:firstAllocation 参数:node* head,int size,charc[10]

void firstAllocation(node* head,int size,char c[10])

{

 //函数功能:对作业进行分段,并采用最先分配,分段结束后打印 段表

}

        //函数名:reorder 参数:node* head

void reorder(node* head)

{

   //函数功能:对分区和未分区的存储区域进行编号 

}

//函数名:recycle 参数:node* head

void recyle(node* head) //回收算法

{

   //函数功能:对归还分区按情况进行处理,,有上邻有下邻,有上邻     无下邻,无上邻有下邻,无上邻无下邻

            

}

//函数名:print参数:node* head

void print(node* head)

{

   //函数功能:打印主存分配表

}

int main()

{

    node* head;

    head=initMemory();

    while(1)

    {

        int c;

        c=operation(head);

        if(c==1)

        {

            break;

        }

    }

    return 0;

}

测试用例:

/*

256

40

1

jobA

50

2

20

30

1

jobB

100

3

30

35

35

2

jobB

2

jobA

0

*/

关键代码

#include<stdio.h>
#include<malloc.h>
#include<string.h>
int g_size; 
//内存结构体
typedef struct memory_node
{int size; //内存大小int address; //内存始址
} memoryNode;memoryNode memory;//分区结构体
typedef struct link_node
{int id;//分区号int size; //分区长度int address; //分区始址char flag[20]; //分区状态,空闲或者占用作业名struct link_node* next;
} node;//段表
typedef struct segment_node
{int sum;char jobname[20];int a[10][10];struct segment_node *next;
} segmentNode;node* initMemory();
node* operation(node *head);
node* allocate(node *head);
node* firstAllocation(node* head,int size,char c[10]);
node* reorder(node* head);
node* recyle(node* head);
void print(node* head);node *distribute = NULL;segmentNode *duanbiao =NULL;//函数名 :initMemory  参数:无
node* initMemory()
{//函数功能:初始化内存空间printf("请输入内存大小:");scanf("%d",&memory.size);g_size = memory.size;printf("请输入起始地址:");scanf("%d",&memory.address);node* p = (node *) malloc ( sizeof(node) * memory.size ); //分配可以放得下265个node的内存空间p->next = NULL;p->id = 1;p->size = memory.size;p->address = memory.address;p->flag[0] = '\0';return p;
}//函数名:operation 参数:node* head
node* operation(node *head)
{
//函数功能:打印操作菜单,选择需要进行的操作,输入1进行内存分配,输入2进行内存去配,输入0退出int choice; printf("*********可变分区管理**********\n");printf("   *     1.内存分配      *\n");printf("   *     2.内存去配      *\n");printf("   *     0.退出          *\n");printf("         请输入选项[ ]\b\b");scanf("%d",&choice);if(choice == 1){printf("1.内存分配\n");reorder(head); print(head);head=allocate(head);}else if(choice == 2){printf("2.内存去配\n");reorder(head);print(head);head=recyle(head); }else{return NULL;}return head;
}
//函数名:allocate 参数:node* head
node* allocate(node *head)
{
//函数名:输入作业名和大小,默认采用最先分配char name[20];int jobsize;printf("请输入作业名:");scanf("%s",&name);printf("请输入%s需要分配的主存大小:",name);scanf("%d",&jobsize);if(jobsize <= g_size)head = firstAllocation(head,jobsize,name);elseprintf("分配失败!");return head;}//函数名:firstAllocation 参数:node* head,int size,charc[10]
node* firstAllocation(node* head,int size,char c[10])
{//函数功能:对作业进行分段,并采用最先分配,分段结束后打印 段表int count = 0,blockNum,jobblocksize,state;node *q,*pre;segmentNode* D = (segmentNode *) malloc ( sizeof(segmentNode) * 1 ); D->next = NULL;strcpy(D->jobname,c);if(duanbiao == NULL) duanbiao = D;else{D->next = duanbiao;duanbiao = D;}q = head;printf("请输入要分成几段:");scanf("%d",&blockNum);D->sum = blockNum;while(count != blockNum){   printf("剩余%dKB的内存,请输入第%d段的大小:",size,count+1);scanf("%d",&jobblocksize);node* p = (node *) malloc ( sizeof(node) * 1 ); p->next = NULL;p->size = jobblocksize;strcpy(p->flag,c);
//      p->flag[strlen(p->flag)+1] = p->flag[strlen(p->flag)];
//      p->flag[strlen(p->flag)]= '0' + count;state = count;while(1){if(state/10 == 0){p->flag[strlen(p->flag)+1] = p->flag[strlen(p->flag)];p->flag[strlen(p->flag)]= '0' + state%10;break;}else{p->flag[strlen(p->flag)+1] = p->flag[strlen(p->flag)];p->flag[strlen(p->flag)]= '0' + state/10;state=state%10;}}while(q!=NULL){if(q->size >= p->size)break;pre = q;q = q->next;}if(q!=NULL){p->address = q->address;if(q->size == p->size){if(q==head)head=NULL;elsepre->next = q->next;}else{q->size = q->size -p->size;q->address = q->address + p->size;}if(distribute == NULL){distribute = p;}else{p->next = distribute;distribute = p;}}else{printf("分配失败!");return head;}D->a[count][0] = jobblocksize;D->a[count][1] = p->address + p->size;count++;size = size - jobblocksize;reorder(head);print(head);}printf("分配成功!\n");printf("************打印%s段表************\n",c);printf("段号\t段长\t基址\n");for(int i=0;i<blockNum;i++)printf("%d\t%d\t%d\n",i,D->a[i][0],D->a[i][1]);return head;
}//函数名:reorder 参数:node* head
node* reorder(node* head) 
{//函数功能:对分区和未分区的存储区域进行编号  int count;node *p;count = 1;p = distribute;while(p!=NULL){p->id = count;count++;p = p->next; }p = head;while(p!=NULL){p->id = count;count++;p = p->next; }return head;
}//函数名:recycle 参数:node* head
node* recyle(node *head) //回收算法
{//函数功能:对归还分区按情况进行处理,有上邻有下邻,有上邻无下邻,无上邻有下邻,无上邻无下邻char name[20];int state;segmentNode *q,*preq;node *qq,*preqq,*qqq,*preqqq;//distribute q = duanbiao;printf("请输入您想回收的作业名:");scanf("%s",&name);while(q!=NULL&&strcmp(q->jobname,name)!=0){preq = q;q = q->next;}if(q==duanbiao){duanbiao=q->next;}else{preq->next=q->next;}if(q==NULL)printf("没有该作业!");else{for(int i=0;i<q->sum;i++){ qq = distribute;//已分配链表 while(qq!=NULL)//在已分配表中找要回收的作业{if(qq->address == q->a[i][1]-q->a[i][0]){if(qq==distribute){distribute = qq->next;}else{preqq->next = qq->next;}break;}preqq = qq;qq = qq->next;}preqqq = NULL;qqq = head;//未分配链表 while(qqq!=NULL)//将要回收的作业的空闲分区合并{if(qq->address+qq->size<head->address)//头没有临界区{qq->next = head;head = qq;printf("回收%s的段%s成功!\n",name,qq->flag);qq->flag[0] = '\0'; break;}else if(qq->address+qq->size == head->address)//头有下{head->address = qq->address;head->size = head->size + qq->size;printf("回收%s的段%s成功!\n",name,qq->flag);break;}else if(preqqq!=NULL&&qq->address == preqqq->address+preqqq->size&&qq->address+qq->size==qqq->address)//有上有下{preqqq->size = preqqq->size+qqq->size+qq->size;preqqq->next = qqq->next;printf("回收%s的段%s成功!\n",name,qq->flag);free(qq);break;}else if(preqqq!=NULL&&qq->address == preqqq->address+preqqq->size&&qq->address+qq->size<qqq->address)//有上没有下{preqqq->size =preqqq->size + qq->size;printf("回收%s的段%s成功!\n",name,qq->flag);free(qq);break;}else if(preqqq!=NULL&&qq->address > preqqq->address+preqqq->size&&qq->address+qq->size==qqq->address)//没有上有下{qqq->address = qq->address;qqq->size = qqq->size+qq->size;printf("回收%s的段%s成功!\n",name,qq->flag);free(qq);break;}else if(preqqq!=NULL&&qq->address > preqqq->address+preqqq->size&&qq->address+qq->size<qqq->address)//没有上没有下{qq->next = qqq;preqqq->next = qq;printf("回收%s的段%s成功!\n",name,qq->flag);qq->flag[0] = '\0';break;}else if(preqqq!=NULL&&qqq->next == NULL&&qqq->address+qqq->size==qq->address)//尾部(有上){qqq->size = qqq->size+qq->size;printf("回收%s的段%s成功!\n",name,qq->flag);break;}else if(preqqq!=NULL&&qqq->next == NULL&&qqq->address+qqq->size<qq->address)// 尾部(没有上){qqq->next = qq;qq->next =NULL;printf("回收%s的段%s成功!\n",name,qq->flag);qq->flag[0]='\0';break;}preqqq = qqq;qqq = qqq->next; }}reorder(head);print(head);free(q);}return head;
}
//函数名:print参数:node* head
void print(node* head)
{//函数功能:打印主存分配表node *p;printf("******************主存分配情况******************\n");p = distribute;printf("已分配:\n");printf("分配号  大小(KB)      起始(KB)      状态\n");while(p!=NULL&&p->flag[0]!='\0'){printf("%d\t%d\t\t%d\t\t%s\n",p->id,p->size,p->address,p->flag);p = p->next;}printf("\n\n\n");p = head;printf("未分配:\n");printf("分配号  大小(KB)      起始(KB)      状态\n");while(p!=NULL&&p->flag[0] == '\0'){printf("%d\t%d\t\t%d\t\t空闲\n",p->id,p->size,p->address,p->flag);p = p->next;}
}int main()
{node* head;head=initMemory();while(1){head=operation(head);if(head==NULL){break;}}return 0;
}

运行结果

实验总结

①对单链表还是不熟,没有头结点的单链表head没有next;

②对链表的遍历条件没有设计好,在该题中preqqq!=NULL才能进行遍历;

③对于指针,如果修改了指针则要返回该指针并赋值给它本身,或者在传递指针时,传的是指针的指针,否则对指针的处理是无效的。

这篇关于操作系统原理与实验——实验十分段存储管理的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/973694

相关文章

现成轮子OSAL操作系统抽象层的移植

简单介绍一下Z-STACK中的OSAL,值得一看的现成轮子; 什么是 OSAL? 今天同学忽然问我有没有搞过OSAL,忽然间一头雾水,于是在搜索引擎上找到了答案,发现这是一个十分实用的东西。 OSAL(operating system abstraction layer),操作系统抽象层,是一种以实现多任务为核心的系统资源管理机制,实现了类似RTOS的某些功能,但并不能称之为真正意义上的RT

Linux内核中container_of的原理及其使用详解

文章目录 前言宏定义如何使用简单分析typeofoffsetof 写在最后 前言 在进行内核驱动开发的时候,经常可以看到container_of的身影,其作用就是获取包含某个成员的结构体变量地址,函数原型如下所示; #define container_of(ptr, type, member) ({ \const typeof( (

PHP中isset、empty、is_null实验测试

#$abc = "abc";     $def;     #var_dump(isset($abc));     //var_dump(empty($def));     //var_dump(false);     //var_dump(empty(''));     var_dump(isset($def));     var_dump(is_null($def));     #

iOS逆向重签名(一):签名原理

目录: 1. iOS逆向重签名(一):签名原理 2. iOS逆向重签名(二):IPA重签名 3. iOS逆向重签名(三):微信重签名 在了解iOS签名原理之前,需要有一定的密码学知识,否则有些东西无法理解。所以在学习iOS签名原理之前,先跟小编一起学习一下简单的密码学知识。 一、简单的密码学知识 1.1 非对称加密算法 非对称加密就是加密和解密使用的不是相同的密钥:只有同一个公钥-私

一个操作系统的实现_十分钟完成的操作系统

步骤: 1.编辑器(例如记事本)写入操作系统启动代码,保存为后缀名为.asm的文件格式         2.安装一款虚拟机软件以wm为例,新建一个虚拟机,注意操作系统与版本都选择其他,创建的最后一步选择[自定义硬件], 进入后选择[添加],选择[软盘驱动器],接着[创建空软盘映像],在虚拟机根目录下任意创建一个后缀名为.img或者.flg的映像文件 (可以新建文本文档,更

研究实验1_搭建一个精简的C语言开发环境(包含部分经典的前言)

综合研究:      在这部分内容中,将启示我们如何进行独立研究和深度思考(一定要注意这一点,相应的调整自己的学习思想)。同时使我们:          (1)认识到汇编语言对于深入理解其他领域知识的重要性。          (2)对前面所学习的汇编语言知识进行融会。          (3)对用研究的方法进行学习进行体验。  研究实验1_搭建一个精简的C语言开发环境:  在运行过

算法工程师面试问题 | YOLOv8面试考点原理全解析(一)

本文给大家带来的百面算法工程师是深度学习目标检测YOLOv8面试总结,文章内总结了常见的提问问题,旨在为广大学子模拟出更贴合实际的面试问答场景。在这篇文章中,我们还将介绍一些常见的深度学习目标检测面试问题,并提供参考的回答及其理论基础,以帮助求职者更好地准备面试。通过对这些问题的理解和回答,求职者可以展现出自己的深度学习目标检测领域的专业知识、解决问题的能力以及对实际应用场景的理解。同时,这也是为

Vue原理学习:vdom 和 diff算法(基于snabbdom)

vdom 和 diff 背景 基于组件化,数据驱动视图。只需关心数据,无需关系 DOM ,好事儿。 但是,JS 运行非常快,DOM 操作却非常慢,如何让“数据驱动视图”能快速响应? 引入 vdom 用 vnode 表示真实 DOM 结构  <div id="div1" class="container"><p>vdom</p><ul style="font-size: 20px">

技术前沿 |【大模型LLaMA:技术原理、优势特点及应用前景探讨】

大模型LLaMA:技术原理、优势特点及应用前景探讨 一、引言二、大模型LLaMA的基本介绍三、大模型LLaMA的优势特点五、结论与展望 一、引言 随着人工智能技术的飞速发展,大模型已成为推动这一领域进步的重要力量。近年来,大模型LLaMA以其卓越的性能和广泛的应用前景,受到了业界的广泛关注。本文旨在深入解析大模型LLaMA的技术原理、优势特点以及可能的应用场景,以期为相关领域

Git版本控制工具的原理及应用详解(四)

本系列文章简介:         随着软件开发的复杂性不断增加,版本控制成为了开发团队中不可或缺的工具之一。在过去的几十年里,版本控制工具经历了各种发展和演变,其中Git无疑是目前最受欢迎和广泛应用的版本控制工具之一。         Git的出现为开发者们带来了许多便利和效率提升,但对于初学者来说,Git的原理和应用可能会显得有些复杂和困惑。本系列文章将详细介绍Git的原理和应用,帮助大家全