操作系统实验-第二次实验报告 - 副本

合集下载

操作系统实验二实验报告

操作系统实验二实验报告

操作系统实验二实验报告一、实验目的本次操作系统实验二的主要目的是深入理解和掌握进程管理的相关概念和技术,包括进程的创建、执行、同步和通信。

通过实际编程和实验操作,提高对操作系统原理的认识,培养解决实际问题的能力。

二、实验环境本次实验使用的操作系统为 Windows 10,编程环境为 Visual Studio 2019。

三、实验内容及步骤(一)进程创建实验1、首先,创建一个新的 C++项目。

2、在项目中,使用 Windows API 函数`CreateProcess`来创建一个新的进程。

3、为新进程指定可执行文件的路径、命令行参数、进程属性等。

4、编写代码来等待新进程的结束,并获取其退出代码。

(二)进程同步实验1、设计一个生产者消费者问题的模型。

2、使用信号量来实现生产者和消费者进程之间的同步。

3、生产者进程不断生成数据并放入共享缓冲区,当缓冲区已满时等待。

4、消费者进程从共享缓冲区中取出数据进行处理,当缓冲区为空时等待。

(三)进程通信实验1、选择使用管道来实现进程之间的通信。

2、创建一个匿名管道,父进程和子进程分别读写管道的两端。

3、父进程向管道写入数据,子进程从管道读取数据并进行处理。

四、实验结果及分析(一)进程创建实验结果成功创建了新的进程,并能够获取到其退出代码。

通过观察进程的创建和执行过程,加深了对进程概念的理解。

(二)进程同步实验结果通过使用信号量,生产者和消费者进程能够正确地进行同步,避免了缓冲区的溢出和数据的丢失。

分析结果表明,信号量机制有效地解决了进程之间的资源竞争和协调问题。

(三)进程通信实验结果通过管道实现了父进程和子进程之间的数据通信。

数据能够准确地在进程之间传递,验证了管道通信的有效性。

五、遇到的问题及解决方法(一)在进程创建实验中,遇到了参数设置不正确导致进程创建失败的问题。

通过仔细查阅文档和调试,最终正确设置了参数,成功创建了进程。

(二)在进程同步实验中,出现了信号量使用不当导致死锁的情况。

操作系统实验报告-实验二

操作系统实验报告-实验二

操作系统实验报告——实验二:C编程环境实验目的1.熟悉Linux下C程序设计的环境;2.对系统调用有初步了解。

实验内容1.Linux下C语言程序的开发过程a、在用户主目录下用vi编辑C语言源程序(源程序已附后),如:$vi hello.c。

b、用gcc编译C语言源程序:$gcc ./hello.c -o example这里gcc是Linux下的C语言程序编译器(GNU C Compiler),./hello.c表示待编译的源文件是当前工作目录下的hello.c,-o example表示编译后产生的目标代码文件名为example。

c、若编译不正确,则进入vi修改源程序,否则,运行目标代码:$./example 。

注意:这只是gcc最基本的用法,其他常用选项有:-c , -S , -O , -O2, -g 等。

2.编辑、调试下面c语言程序,说明该程序的功能。

#include <stdio.h>#include <stdlib.h>int main() {int n,a[200],carry,temp,i,j,digit = 1;printf("Please input n:");scanf("%d",&n);a[0] = 1;for( i = 2; i <= n; ++i) {for( j = 1, carry = 0; j <= digit; ++j) {temp = a[j-1] * i + carry;a[j-1] = temp % 10;carry = temp / 10;}while(carry) {a[++digit-1] = carry % 10;carry /= 10;}}printf("Result is:\n%d ! = ",n);for( i = digit; i >=1; --i) {printf("%d",a[i-1]);}printf("\n");return 0;}程序运行结果截图:程序实现功能:计算非负数的阶乘,阶乘运算的结果的个位十位百位……分别保存在a[0],a[1],a[2]……3.编写命令解释程序(1)内容:利用C语言编写一个微型命令解释程序,接受并解释以下命令:1.dir //列当前目录2.cop 文件1 文件2 //拷贝文件3.era文件名//删除文件4.dis字符串//显示字符串5.end //结束,退出(2)要求:1.命令应该由空格隔开;2.进行命令合法性检查,若不合法,显示出错信息,等待重新输入;3.调用shell命令来完成各项功能。

操作系统lab2实验报告

操作系统lab2实验报告

操作系统lab2实验报告实验目的:本实验的目的是通过设计和实现一个简单的操作系统内核,加深对操作系统基本概念和原理的理解。

具体实验内容包括进程管理、内存管理和文件系统的设计与实现。

实验环境:1.操作系统:Linux2.编程语言:C语言一、实验背景1.1 操作系统简介操作系统是计算机系统中的一个重要组成部分,负责管理和控制计算机的各种资源,提供用户和应用程序的接口,以及协调和调度各种任务的执行。

1.2 实验目标本实验的主要目标是设计和实现一个简单的操作系统内核,包括进程管理、内存管理和文件系统等功能。

二、实验内容2.1 进程管理①进程创建描述进程创建的过程和相关数据结构,包括创建新进程的系统调用、进程控制块等。

②进程调度描述进程调度的算法和实现方式,包括进程调度队列、调度算法等。

③进程同步与通信描述进程同步和通信的机制和方法,包括信号量、互斥锁、条件变量等。

2.2 内存管理①内存分配描述内存分配的算法和实现方式,包括连续内存分配、非连续内存分配等。

②页面置换描述页面置换的算法和实现方式,包括最优页面置换算法、先进先出页面置换算法等。

2.3 文件系统①文件操作描述文件操作的系统调用和相关数据结构,包括文件打开、读写、关闭等。

②文件系统结构描述文件系统的组织结构和实现方式,包括超级块、索引节点、块位图等。

三、实验步骤3.1 环境搭建搭建实验环境,包括安装Linux操作系统、编译器等。

3.2 进程管理实现根据设计要求,实现进程创建、调度、同步与通信等功能。

3.3 内存管理实现根据设计要求,实现内存分配、页面置换等功能。

3.4 文件系统实现根据设计要求,实现文件操作和文件系统结构。

3.5 测试与调试编写测试用例,对实现的操作系统内核进行测试和调试,并记录实验结果。

四、实验结果分析分析测试结果,评估实验过程中遇到的问题和解决方法,总结操作系统内核的性能和功能特点。

五、实验总结对实验过程中的收获和经验进行总结,提出改进和优化的建议。

《操作系统》实验报告(3) (2)

《操作系统》实验报告(3) (2)
任务四:修改后的程序代码是:
#include <stdio.h>
main(){
int p1, p2;
while ((p1=fork())==-1);
if (p1==0)
printf(“this is the child1 process!\n”);
else {
while ((p2=fork())==-1);
exit(0);}
else if(pid==0)
{execl(“/bin/ls”,”ls”,”-al”,”/etc/passwd”,(char *)0);
exit(0);}
else
{pid=waitpid(pc,NULL,0);
printf(“the child process:%d\n”,pid);}
while ((p2=fork())==-1);/*父进程创建第二个进程,直到成功*/
if (p2==0)/* 0返回给子进程2*/
putchar(‘c’);/*子进程2的处理过程*/
else putchar(‘a’);/*子进程2创建完成后,父进程的处理过程*/}
}
多次运行结果大多数都是bca,偶尔会出现bac或者cab。进程的处理过程太短,多次运行可能出现差错。
任务6:编写一段程序,使用系统调用fork( )创建一个子进程。子进程通过系统调用exec系列函数调用命令ls,调用exit( )结束。而父进程则调用waitpid( )等待子进程结束,并在子进程结束后显示子进程的标识符,然后正常结束。
创建进程的系统调用:
fork( ),创建一个新进程。
系统调用格式:pid=fork( );
}
任课教师签名:2011年4月日

操作系统实习二报告

操作系统实习二报告

实验二主存储器空间的分配和回收一、实验题目:模拟在分页式管理方式下采用位示图来表示主存分配情况,实现主存空间的分配和回收。

二、实验目的:主存的分配和回收的实现与主存储器的管理方式有关,通过本实习理解在不同的存储管理方式下应怎样实现主存空间的分配和回收。

三、实验内容:一个好的计算机系统不仅要有一个足够容量的、存取速度高的、稳定可靠的主存储器,而且要能合理地分配和使用这些存储空间。

当用户提出申请存储器空间时,存储管理必须根据申请者的要求,按一定的策略分析主存空间的使用情况,找出足够的空闲区域分配给申请者。

当作业撤离或主动归还主存资源时,则存储管理要收回作业占用的主存空间或归还部分主存空间。

四、程序中使用的数据结构及符号说明:五、程序流程图:六、程序源代码:#include <stdlib.h>#include <stdio.h>typedef int datatype;typedef struct node{datatype pageNum,blockNum;struct node *next;}linknode;typedef linknode *linklist;linklist creatlinklist(int n)/*尾插法创建带头结点的单链表*/{linklist head,r,s;int x,y,i=0;head=r=(linklist)malloc(sizeof(linknode));printf("\n请分别输入页表的页号及块号(-1表示空):\n");printf("\n页号| 块号\n");while (i<n){scanf("%d %d",&x,&y);s=(linklist)malloc(sizeof(linknode));s->pageNum=x;s->blockNum=y;r->next=s;r=s;i++;}r->next=NULL;return head;}void init(int g[100][100],int N)/*初始化位示图,将值全置为零,0表示空闲状态*/{int i,j;for(i=0;i<100;i++){for(j=0;j<100;j++){g[i][j]=0; //全置为零}}g[N+1][0]=N*N; //在数组最后一个数的后面设置一个空间用来存放剩余空闲块数}linklist Init(linklist head,int g[100][100],int n,int N){linklist p;int i,j;p=head->next;if(n<=g[N+1][0]) //首先判断作业的页数是否小于等于位示图剩余空闲块的个数{while(p){i=p->blockNum/N;j=p->blockNum%N;g[i][j]=1;g[N+1][0]--;p=p->next;}}return head;}printStr(int g[100][100],int N)/*打印位示图*/{int i,j;printf("\n此时位示图为:\n");printf("\n ");for(i=0;i<N;i++){printf(" ");printf("%d",i);}printf("\n");for(i=0;i<N;i++){printf("%d",i);for(j=0;j<N;j++){printf(" ");printf("%d",g[i][j]);}printf("\n");}printf("\n");}void print(linklist head)/*输出带头结点的单链表*/{linklist p;p=head->next;printf("\n该页表为:\n");printf("\n");printf("\n 页号| 块号\n");while(p){printf("%11d%7d\n",p->pageNum,p->blockNum);p=p->next;}printf("\n");}linklist Dis(linklist head,int g[100][100],int n,int N){linklist p;int i,j;p=head->next;if(n<=g[N+1][0]) //首先判断作业的页数是否小于等于位示图剩余空闲块的个数{while(p){for(i=0;i<N;i++){for(j=0;j<N;j++){if(g[i][j]==0){p->blockNum=N*i+j; //将对应块号记录到页表g[i][j]=1; //将块置1,表示已被占用g[N+1][0]--; //剩余空闲块减1break; //跳出循环,进行下一个页的分配}}break; //跳出循环}p=p->next; //下一个页进行分配}return head;}}linklist Recy(linklist head,int g[100][100],int n,int N)/*回收已经完成的页*/ {int i,j;linklist p;p=head->next;while(p&&p->pageNum!=n) //找出要回收的页号{p=p->next;}if(p) //找到{i=p->blockNum/N;j=p->blockNum%N;g[i][j]=0; //将该块置0,表空闲状态g[N+1][0]++;p->blockNum=-1; //页表中对应的块号为空,置成-1}return head;}void main(){int m,n,N;int x,y,a,b,t;int graph[100][100];linklist head,Head;printf("\n*****分页式存储管理分配及回收算法*****\n");printf("\n请输入位示图字长:");scanf("%d",&N);printf("\n请输入已占用内存作业的页数:");scanf("%d",&m);head=creatlinklist(m);init(graph,N);head=Init(head,graph,m,N);printStr(graph,N);printf("\n当前空闲块数为:%d",graph[N+1][0]);printf("\n\n现在进行作业分配:\n");printf("\n请输入需要分配的作业的页数:");scanf("%d",&n);Head=creatlinklist(n);Head=Dis(Head,graph,n,N);print(Head);printStr(graph,N);printf("\n当前空闲块数为:%d",graph[N+1][0]);printf("\n\n您是否想回收已完成的页,“是”请按1,“否”请按0:");scanf("%d",&x);if(x) //判断是否要回收{printf("\n请输入您要回收的页号:");scanf("%d %d %d %d",&y,&a,&b,&t);head=Recy(head,graph,y,N);head=Recy(head,graph,a,N);head=Recy(head,graph,b,N);head=Recy(head,graph,t,N);printStr(graph,N);}printf("\n当前空闲块数为:%d",graph[N+1][0]);printf("\n");}七、运行结果:实习小结:本次实验是自己花了很多的时间去琢磨去尝试才完成的,虽然还不是很完美,但是在设计的过程中自己在对编程方面的逻辑思维得到了很好的锻炼。

Linux操作系统第二次实验报告

Linux操作系统第二次实验报告
实验内容及实验记录:
1.打开终端窗口。在当前目录下,创建测试目录*test(其中*为学生姓名拼音首字母组合)。
2.利用ls命令列出文件和目录,确认*test目录创建成功。
3.进入test目录,利用pwd命令查看当前工作目录。
4.利用touch命令,在当前目录创建一个新的空文件*file(其中*为学生姓名拼音首字母组合)。
15.进入*test目录,显示目录中的文件列表。查找当前用户的主目录下的所有名为*file的文件。
16.删除*test子目录下的所有文件。利用rmdir命令删除空目录*test。
17.回到上层目录,利用rm命令删除目录*test和其下所有文件。
指导教师评语:
实验报告
课程名称:Linux操作系统
任课教师:
授课学期:
学生班级:
学生姓名:
实验题目:文件和目录的命令行操作
实验成绩:
指导教师:
实验室:
日期:
节数:2
实验目的:
1.熟悉各类文件操作命令。
2.掌握基于命令行的文件操作。
3.熟悉目录操作命令。
4.掌握基于命令行的目录操作。
实验仪器、物品:已安装好Ubuntu桌面操作系统。
12.删除文件profile,用长格式显示文件lnsprofile和lnhprofile的详细信息,比较文件lnhprofile的链接数的变化。
13.把文件*file(其中*为学生姓名音首字母组合)改名为backupfile。显示当前目录下的文件和目录列表,确认重命名成功。
14.把文件backupfile移动到*test目录下。显示当前目录下的文件和目录列表,确认移动成功。
9.用grep命令在profile文件中对关键字then进行查询,并与上面的结果比较。

操作系统实验报告实验二

操作系统实验报告实验二一、实验目的本次操作系统实验二的目的在于深入理解和掌握操作系统中的进程管理和进程调度相关知识,通过实际的编程和实验操作,观察和分析不同进程调度算法的性能和效果,提高对操作系统核心概念的理解和应用能力。

二、实验环境本次实验在 Windows 10 操作系统下进行,使用 Visual Studio 2019作为编程工具。

实验中涉及的编程语言为 C++。

三、实验内容(一)进程创建与控制编写程序实现创建多个进程,并通过进程控制原语(如创建、等待、终止等)对进程进行管理和控制。

(二)进程调度算法实现1、先来先服务(FCFS)调度算法按照进程到达的先后顺序进行调度,先到达的进程先获得 CPU 资源进行执行。

2、短作业优先(SJF)调度算法优先调度执行时间短的进程,以减少平均等待时间。

3、时间片轮转(RR)调度算法将 CPU 时间划分为固定大小的时间片,每个进程在一个时间片内执行,时间片结束后切换到下一个进程。

(三)性能评估指标1、平均等待时间所有进程等待时间的总和除以进程数量。

2、平均周转时间所有进程周转时间的总和除以进程数量。

周转时间为进程从提交到完成的时间间隔。

四、实验步骤(一)进程创建与控制1、定义进程结构体,包含进程 ID、到达时间、执行时间等信息。

2、使用系统调用或库函数创建进程。

3、在父进程中通过等待函数等待子进程结束,并获取子进程的返回状态。

(二)进程调度算法实现1、先来先服务(FCFS)调度算法按照进程到达时间的先后顺序将进程放入就绪队列。

从就绪队列中取出第一个进程进行调度执行。

2、短作业优先(SJF)调度算法计算每个进程的执行时间。

按照执行时间从小到大的顺序将进程放入就绪队列。

从就绪队列中取出执行时间最短的进程进行调度执行。

3、时间片轮转(RR)调度算法将进程按照到达时间先后顺序放入就绪队列。

为每个进程分配一个时间片,当时间片用完后,将进程放入就绪队列尾部,重新调度下一个进程。

操作系统Lab2实验报告


深入学习 操作系统的原理和实 现细节,包括进程通 信、死锁处理、虚拟 化技术等。
实践应用
希望将所学的操作系 统知识应用到实际项 目中,提高自己的实 践能力。
持续学习
随着技术的不断发展 ,操作系统也在不断 更新和进步,需要保 持持续学习的态度。
探索新领域
对于新兴的操作系统 领域,如云操作系统 、物联网操作系统等 ,也希望有所涉猎和 探索。
学生将了解操作系统内核的组成和功能,以及操作系统如何通过内核 实现各种基本功能。
学生将通过实验深入了解操作系统的内部实现细节,提高自己对操作 系统设计和实现的认知水平。
02
实验内容
进程管理实验
总结词
理解进程状态及其转换、进程控制块PCB的组成、进程调度算法。
详细描述
通过实验,我们深入了解了进程的概念、状态及其转换。进程控制块PCB的组成,包括进程标 识符、进程状态、优先级、CPU寄存器内容等信息。此外,我们还学习了进程调度算法,如先 来先服务、最短作业优先、优先级调度等,并进行了模拟实验。
THANKS
感谢观看
操作系统Lab2实验 报告
汇报人:
202X-01-08
目录
• 实验目的 • 实验内容 • 实验结果与分析 • 问题与改进建议 • 总结与展望
01
实验目的
理解操作系统的基本概念
01
掌握核心概念
02
操作系统是计算机系统的核心软件,负责管理计算机硬件和软件资源 ,为用户提供便利的操作界面和高效的服务。
03
操作系统具有并发性、虚拟性、异步性和随机性的特点,这些特点决 定了操作系统在计算机系统中的重要地位和作用。
04
操作系统的基本功能包括进程管理、内存管理、文件管理和设备管理 ,这些功能是操作系统实现其核心目标的基础。

北邮计算机科学与技术操作系统第二次实验

北京邮电大学操作系统第二次实验实验报告班级302班第一部分:内存管理的伙伴算法1.实验描述:实现一个内存管理的伙伴算法,实现内存块申请时的分配和释放后的回收。

用随机函数仿真进程进行内存申请,并且以较为随机的次序进行释放。

对其碎片进行统计,当申请分配内存失败时区分实际空间不足和由于碎片而不能满足。

2.实验原理解释:假设要求分配的块其大小为128个页面。

该算法先在块大小为128个页面的链表中查找,看是否有这样一个空闲块。

如果有,就直接分配;如果没有,该算法会查找下一个更大的块,具体地说,就是在块大小为256个页面的链表中查找一个空闲块。

如果存在这样的空闲块,内核就把这256个页面分为两等份,一份分配出去,另一份插入到块大小为128个页面的链表中。

如果在块大小为256个页面的链表中也没有找到空闲页块,就继续找更大的块,即512个页面的块。

如果存在这样的块,内核就从512个页面的块中分出128个页面满足请求,然后从384个页面中取出256个页面插入到块大小为256个页面的链表中。

然后把剩余的128个页面插入到块大小为128个页面的链表中。

如果512个页面的链表中还没有空闲块,该算法就放弃分配,并发出出错信号。

以上过程的逆过程就是块的释放过程,这也是该算法名字的来由。

满足以下条件的两个块称为伙伴:两个块的大小相同,两个块的物理地址连续。

伙伴算法把满足以上条件的两个块合并为一个块,该算法是迭代算法,如果合并后的块还可以跟相邻的块进行合并,那么该算法就继续合并。

3.试验运行截图:第一组数据测试截图:第二组数据测试截图:第三组数据测试截图:4.实验代码:#include<iostream>#include<stdio.h>#define GETMIN(a,b) ((a)<(b)?(a):(b)) #define GETMAX(a,b) ((a)>(b)?(a):(b)) using namespace std;struct Node{int size;int remain;int frag;int isSplit;Node *left;Node *right;Node *parent;};struct Process{int oriMem;int reqMem;Node *ptr;void init(int _oriMem){int i;if(_oriMem<=0){oriMem=0;reqMem=0;ptr=NULL;return;}oriMem=_oriMem;for(i=31;i>=0;i--){if(oriMem&(1<<i)){break;}}if(oriMem==1<<i){reqMem=oriMem;}else{reqMem=1<<(i+1);}ptr=NULL;}};class BuddyTree{private:Node *root;Node *newNode(Node *_parent,int _size,int _remain){Node *ptr=new(Node);ptr->size=_size;ptr->remain=_remain;ptr->frag=0;ptr->isSplit=0;ptr->left=NULL;ptr->right=NULL;ptr->parent=_parent;return ptr;}public:Node* getRoot(){return root;}void init(int MaxMem){root=newNode(NULL,MaxMem,MaxMem);}void requestMem(Node *ptr,Node *&res,int reqSize,int oriSize){ if(ptr->remain<reqSize){res=NULL;return;}if(ptr->size==reqSize){res=ptr;ptr->remain=0;ptr->frag+=reqSize-oriSize;return;}if(ptr->isSplit==0){int _size=ptr->size/2;ptr->isSplit=1;ptr->left=newNode(ptr,_size,_size);ptr->right=newNode(ptr,_size,_size);requestMem(ptr->left,res,reqSize,oriSize);}else{int minMem=GETMIN(ptr->left->remain,ptr->right->remain); if(minMem>=reqSize){if(ptr->left->remain<=ptr->right->remain){requestMem(ptr->left,res,reqSize,oriSize);}else{requestMem(ptr->right,res,reqSize,oriSize);}}else{if(ptr->left->remain>=reqSize){requestMem(ptr->left,res,reqSize,oriSize);}else{requestMem(ptr->right,res,reqSize,oriSize);}}}ptr->remain=GETMAX(ptr->left->remain,ptr->right->remain);ptr->frag=ptr->left->frag+ptr->right->frag;}void releaseMem(Node *ptr){int memsize=ptr->size;int frag=ptr->frag;ptr->frag=0;ptr->remain=memsize;ptr=ptr->parent;while(ptr){if(ptr->left->remain==ptr->left->size&&ptr->right->remain==ptr->right->size){ ptr->remain=ptr->size;}else{ptr->remain=GETMAX(ptr->left->remain,ptr->right->remain);}ptr->frag-=frag;ptr=ptr->parent;}}void printTree(Node *ptr){if(ptr==NULL)return;char tmp[100];sprintf(tmp,"[Node size %dB]",ptr->size);printf("%-26s",tmp);sprintf(tmp,"remaining : %dB",ptr->remain);printf("%-26s",tmp);sprintf(tmp,"fragment : %dB",ptr->frag);printf("%s\n",tmp);printTree(ptr->left);printTree(ptr->right);}};Process P[200];int test[3][20]={{24,80,4600,8,100,1,500},{70,480,3300,25,10600,8909,490,99,40},{1,20,300,4000,50000,600000,7000000,80000000,900000000}}; int n[3]={7,9,9};int memory[3]={1024,1024*1024,1024*1024*1024};int main(){BuddyTree BT;char tmp[100];for(int t=0;t<3;t++){printf("Test%d:\n",t+1);printf("Process status:\n");for(int j=0;j<n[t];j++){P[j].init(test[t][j]);sprintf(tmp,"Original request: %d",P[j].oriMem);printf("%-30s",tmp);sprintf(tmp,"Actual request: %d",P[j].reqMem);printf("%s\n",tmp);}printf("\nMemory amount : %dB\n",memory[t]);BT.init(memory[t]);printf("\n");printf("Constructing the tree:\n");for(int j=0;j<n[t];j++){sprintf(tmp,"The process needs %d bytes.",P[j].oriMem);printf("%-35s",tmp);BT.requestMem(BT.getRoot(),P[j].ptr,P[j].reqMem,P[j].oriMem);if(P[j].ptr){printf("Request success,obtain %d bytes.\n",P[j].reqMem);}else{printf("Request failed.\n");}}printf("\n");printf("After constructing,preorder the tree:\n");BT.printTree(BT.getRoot());printf("\n");printf("After constructing the tree,the sum of fragment is %d.\n",BT.getRoot()->frag);printf("\n");printf("After the release,the tree(preorder) is:\n");for(int j=0;j<n[t];j++){if(P[j].ptr){BT.releaseMem(P[j].ptr);}}BT.printTree(BT.getRoot());printf("\n");printf("\n");system("pause");printf("\n");}return 0;}第二部分:设计一个虚拟存储区和内存工作区,并使用下述算法计算访问命中率1.实验描述:设计一个虚拟存储区和内存工作区,并使用下述算法计算访问命中率。

操作系统第二次实验报告

semctl(semid,1,IPC_RMID,0);
semctl(semid,2,IPC_RMID,0);
semctl(semid,3,IPC_RMID,0);
gettimeofday(&_end,NULL);
exe_time = ((float)(__sec - __sec)*1000000+(float)(__usec - __usec))/1000000;
2)利用Linux操作系统提供的信号量工具实现进程间的同步;
3)掌握对共享内存的相关操作;
4)基于生产者-消费者同步的原理实现双缓冲区的誊抄。

任意选择一个文本文件,采用并发进程实现文件誊抄,将其复制为另一个文件。
创建get、copy、put三个进程共用两个缓冲区s、t。get进程负责不断地把原始文件内容送入缓冲区s中,copy进程负责从缓冲区s中取出上述内容复制到缓冲区t中,而put进程负责把上述内容从缓冲区t中取出复制到目标文件中,用p、v操作实现这三个进程之间的同步。
}
int V(int semid, int semnum) {
struct sembuf sops = {semnum, +1, SEM_UNDO};
return (semop(semid, &sops, 1));
}
int main()
{
//定义共享缓冲区,获得一个共享内存的标志,新建内存为1KB
int readbuf_id=shmget(231,CACHE_LENGTH,IPC_CREAT|0666);
}
}
//put_porcess
if((put_id=fork())==0){
if((fout=fopen("./put.txt","wb"))==NULL)
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

操作系统第二次实验报告
目录
第一次实验遗漏的测试: (4)
实验一 (6)
(1.1)认识保护模式 (6)
(1.2)保护模式的运行环境 (7)
实验二:GDT (9)
实验三:LDT (12)
实验四:调用门 (13)
实验五: (15)
(5.1)进入ring3 (15)
(5.2) 调用门进入有特权级变换的转移 (15)
(5.3)经由局部任务返回实模式(pmtest5.asm) (16)
实验六:编写代码启动分页机制(pmtest6.asm) (17)
实验七:显示内存信息(pmtest7.asm) (19)
实验八:页表切换(pmtest8.asm) (20)
实验九: (21)
(9.1)编程操作8259A(pmtest9a.asm) (21)
(9.2)实现一个中断(pmtest9b.asm) (22)
(9.3) 修改IDT,新增函数处理中断(pmtest9c.asm) (23)
(9.4) 时钟中断实验(pmtest9.asm) (24)
实验分析 (26)
个人总结 (26)
一.实验目的:
1.熟悉保护模式
2.学习理解页式存储
3.学习理解中断与异常
4.理解保护模式下的I/O
二.实验内容
1.学习保护模式的运行环境
2.学习GDT、实模式到保护模式的转换
3.理解描述符的属性
4.学习LDT、特权级的概念
5.理解分页机制、PDE与PTE
6.理解中断与异常机制,实现一个中断
7.认识保护模式下的I/O,学习IOPL与I/O许可位图
三.实验环境
Windows10, ubuntu14.04.4
四.关键技术:
汇编语言入门
Nasm编译
五.设计与实验过程、测试过程与测试结果
第一次实验遗漏的测试:
经测试,我安装的bochs不支持dump_cpu指令,因此选用其他的指令查看寄存器情况。

查看结果如下所示
实验一
本次实验分为9个实验,分别自下文介绍。

(1.1)认识保护模式
1.按照书中所说输入下列代码以实现实模式到保护模式的转换,文件命名为pmtest1.asm,
部分截图如下
2.按照书中所说在pm.inc中定义宏,部分截图如下:
3.输入下列命令编译,再将第一次实验用过的软盘映像a.img和Bochs的配置文件bochsrc 复制到当前文件夹,并将生成的二进制写入软盘映像:
4.测试结果如下图所示,屏幕右侧有一个红色的P打印出来。

(1.2)保护模式的运行环境
1.在Bochs的官网(/diskimages.html)上下载一个freedos-img.tar.gz,解压后将其中的a.img改名为freedos.img:
2.用bximage生成一个软盘映像(安装好bochs后附带的程序,直接bximage运行,按回车提示执行),生成名为pm.img的软盘镜像文件
3.修改当前工作目录下的bochsrc,确保其中有以下三行:
4.启动bochs ,待FreeDos启动完毕后格式化B盘:format b:回车:
5.将上节的代码pmtest1.asm 中的org 07c00h 改为org 100h,并重新编译,再将复制到pm.img上:
6.重新运行bochs ,A:/>B: 切换到B盘,执行 ,得到下图所示结果,屏幕右侧打印出红色P
实验二:GDT
1.输入GDT、数据段和堆栈段部分代码如下
2.32位代码段,部分代码如下
3.初始化数据段描述符
4.保护模式到实模式
5.保护模式到实模式的准备工作
6.回到实模式
7.编译
8.挂载
9.运行,结果如下所示,屏幕下方打印红色“in protect mode now”和一串数字
实验三:LDT
1.LDT增加的代码内容:在GDT中增加一个描述符,与描述符对应的选择子,以及初始化代码
2.编译并运行
3. 运行,结果如下所示,屏幕下方打印红色“in protect mode now”和一个L
实验四:调用门
1.通过调用门转移的目标段:
2.上述代码段的描述符:
3.调用门:
4.编译
5. 运行,结果如下所示,屏幕下方打印红色“in protect mode now”和一个L和一个C。

实验五:
(5.1)进入ring3
1.编译
2.运行,结果如下所示,屏幕下方打印红色“in protect mode now”和一个3。

(5.2) 调用门进入有特权级变换的转移
1.进入死循环(pmtest5b.asm):
2.进入死循环之前增加调用门指令(pmtest5c.asm)
3.运行pmtest5c.om,结果如下所示,屏幕下方打印红色“in protect mode now”和一个3和一个C
(5.3)经由局部任务返回实模式(pmtest5.asm)
调试后运行,屏幕下方打印红色“in protect mode now”和一个3和一个C。

实验六:编写代码启动分页机制(pmtest6.asm)
1.在pmtest
2.asm的基础上修改,把实验内存写入和读取的描述符,代码及数据去掉,添加一个函数SetupPaging,代码如下图
2.代码写好后进行编译
3.调试后运行,屏幕下方打印红色“in protect mode now”.
实验七:显示内存信息(pmtest7.asm)1.对代码进行修改后编译
2.调试后运行,屏幕下方打印白色的五段内存信息.
实验八:页表切换(pmtest8.asm)
1.增加一个段,并添加对应的代码,如下图所示
2.把所有的代码编写完成后进行编译。

3.调试后运行,运行后屏幕除了打印五段内存还打印了红色的bar,说明内存的页表切换机制起作用了。

实验九:
(9.1)编程操作8259A(pmtest9a.asm)
1.把设置8259A的代码写进一个函数Init8259A,如下所示
2. 把所有的代码编写完成后进行编译。

3.调试完成后运行,结果显示五段内存及红色的foo和bar.
(9.2)实现一个中断(pmtest9b.asm)
1.调用这个中断
2.进行编译。

3.调试后运行,屏幕打印红色的“!”,程序进入死循环。

(9.3) 修改IDT,新增函数处理中断(pmtest9c.asm)1.修改IDT并增加函数来处理这个中断
2.对修改后的代码进行编译。

3.调试后运行,屏幕打印红色的“I”,程序没有进入死循环。

(9.4) 时钟中断实验(pmtest9.asm)
1,写一个时钟中断程序
2.修改之前所写的代码,并进行编译。

3.调试后运行,屏幕循环打印红色的字符,跳动的字符显示见附件。

gif文件见附件
实验分析
1.编写文件时总是会有写错的情况,查错了很多次,以后要注意。

2.注意运行dos时要先进入b盘。

3.提示挂载点/mnt/floopy不存在,添加指令:sudo mkdir /mnt/floppy
4.不同权限之间的跳转理解要更深入
5.注意段的定义。

个人总结
通过这次试验,我仔细阅读了实验书的第三章,基本了解了一个简单的操作系统是怎么工作的,还有操作系统是怎么在不同权限ji3之间跳转的,并在此基础上自己动手写了几个简单的程序,虽然只是显示了一些简单的字符,但我深刻的体会了之前学的理论知识转化为实际内容的快乐。

相关文档
最新文档