操作系统—河海大学文天学院
姓 名: 胡 德 伟
班 级: 08级计算机科学与技术四班
指导老师: 邓老师
时 间: 2010.12.10
实验一 进程调度
一、实验目的
通过一个简单的进程调度模拟程序的实现,加深对进程调度算法,进程切换的理解。
二、实验内容
采用动态优先数的方法,编写一进程调度程序模拟程序。模拟程序只进行相应的调度模拟操作,不需要实际程序。
[提示]:
(1) 假定系统有五个进程,每一个进程用一个进程控制块PCB来代表,进程控制块的格式为:
进程名
指针
要求
对教师党员的评价套管和固井爆破片与爆破装置仓库管理基本要求三甲医院都需要复审吗
运行时间
优先数
状态
其中,进程名——作为进程的标识,假设五个进程的进程名分别为P1,P2,P3,P4,P5。
指针——按优先数的大小把五个进程连成队列,用指针指出下一个进程的进程控制块的首地址,最后一个进程中的指针为“0”。
要求运行时间——假设进程需要运行的单位时间数。
优先数——赋予进程的优先数,调度时总是选取优先数大的进程先执行。 状态——可假设有两种状态,“就绪”状态和“结束”状态。五个进程的初始状态都为“就绪”,用“R”表示,当一个进程运行结束后,它的状态为“结束”,用“E”表示。
(2) 在每次运行你所
设计
领导形象设计圆作业设计ao工艺污水处理厂设计附属工程施工组织设计清扫机器人结构设计
的处理器调度程序之前,为每个进程任意确定它的“优先数”和“要求运行时间”。
(3) 为了调度方便,把五个进程按给定的优先数从大到小连成队列。用一单元指出队首进程,用指针指出队列的连接情况。
(4) 处理器调度总是选队首进程运行。采用动态改变优先数的办法,进程每运行一次优先数就减“1”。由于本实习是模拟处理器调度,所以,对被选中的进程并不实际的启动运行,而是执行:
优先数-1
要求运行时间-1
来模拟进程的一次运行。
提醒注意的是:在实际的系统中,当一个进程被选中运行时,必须恢复进程的现场,让它占有处理器运行,直到出现等待事件或运行结束。在这里省去了这些工作。
(5) 进程运行一次后,若要求运行时间?0,则再将它加入队列(按优先数大小插入,且置队首标志);若要求运行时间=0,则把它的状态修改成“结
束”(E),且退出队列。
(6) 若“就绪”状态的进程队列不为空,则重复上面(4)和(5)的步骤,直到所有进程都成为“结束”状态。
(7) 在所设计的程序中应有显示或打印语句,能显示或打印每次被选中进程的进程名以及运行一次后进程队列的变化。
(8) 为五个进程任意确定一组“优先数”和“要求运行时间”,启动所设计的处理器调度程序,显示或打印逐次被选中进程的进程名以及进程控制块的动态变化过程。
三(进程调度处理过程
计时中断
中断总处理过程 计时中断处理
修改g_needReschedule当前进程 否 是 为 true 是否用完
是 执行调度算法选择下一g_needReschedul e 个进程
否
切换到下一个进程(此进程可以是原来的
进程也可以是调度算法选择的进程)
四(源程序
分析
定性数据统计分析pdf销售业绩分析模板建筑结构震害分析销售进度分析表京东商城竞争战略分析
/*08计算机 学号:08031421*/ //操作系统,进程调度 用链表实现 #include
#include
#include
#include typedef struct pcb//进程的PCB块 {
char id;//进程名
char state;//进程的状态
int prior;//进程的优先级
int time;//进程的时间
pcb *next;//指向结构体的指针 }pcb,*plist;
void insert(plist &head,pcb *p)
//动态的根据条件,将链表插入到合适的位置中去
{
pcb *s,*r;
if(head->next==NULL) //如果head 指针为空,则应该插入到对头
{
head->next=p;
p->next=NULL; }
else
{
s=head;
r=s->next;
while(r!=NULL&&r->prior>=p->prior) //根据s,r的位置去确定p的插入的位置 {
s=r;
r=r->next; }
//找到新节点q的插入位置,循环后,q节点应该处于结点s,r之间,
//如果r为空,则未尾结点
p->next=r;
s->next=p; }
}
{
pcb *m;
//cout<<"***************************************"<next)
{
p=p->next;
cout<<" "<id<<" "<prior<<"
"<time<<" "<state;
cout<next;
if(m->time==0)
{
cout<<""<id<<"进程已经运行完毕,要从链表中删除<next=head->next->next; //将该结点从链表中删除
}
else
{
head->next=m->next;//对头结点进行重新插入
insert(head,m);
}
cout<<"***************************************"<>p->id>>p->prior>>p->time;
p->state='r'; //初始的转台全部为r
insert(head,p); //将结点插入到合理的位置
}
}
void yunxing(plist &head)//对头结点进行的操作 {
pcb *m;
cout<<"开始进程调度";
cout<next!=NULL) {
m=head->next;
cout<<"进程"<id<<"被调度,时间数和优先级都减1。";
m->prior=m->prior-1;
m->time=m->time-1; if(m->time==0) //如果头结点已经运行完,将状态改为e
head->next->state='e';
showjincheng(head);
}
}
void main()
{
clock_t start,finish;
double shijian;
int a; //进程数
int b; //是否确认
do //确认用户的选择,如果输入错误,可以重新输入
{
do //控制进程的数目在合理的范围内 {
system("cls");
cout<>a;
if(a>=10||a<0)
{
if(a>=10)
cout<<"您所创建的进程数不能大于10,请重新输入"<=10||a<0);
cout<<"您所创建的进程数为"<>b;
if(b==0)
{
system("cls");
cout<<"请重新输入您所创建的进程的数目";
cin>>a;
}
} while (b==0);
cout<<"尊敬的用户,您所创建的进程数为"<next=NULL;
create(head,a);//通过插入的方法构造链表
cout<
#include //队列
#include //获取系统的时间
using namespace std;
typedef struct //页面的结构体信息
{
int id; //页面的id号
int staytime; //在内存中的停留的时间
int unusualtime; //多久未被使用的时间
}Cpage;
deque queue; //可以直接的使用队列的方法 deque interPage; //内存中的页面 deque exterPage; //外存中页面 int xianzaiweizhi;
int lacknum[2] ={0,0}; //缺失的页面数
int getRandNum(int range) //返回[0,range)范围内的整数 {
return int(rand()%range); //根据srand函数得到随机数 }
void InitDevice() //初始化运行队列 按照25% 50% 25%的
标准
excel标准偏差excel标准偏差函数exl标准差函数国标检验抽样标准表免费下载红头文件格式标准下载
生成
{
srand(int(time(NULL))); //通过调用系统时间,产生随机数,并强制的转化成整型
int yehao = getRandNum(320); //随机选择第一条指令
queue.push_back(yehao); //将其插入队列
if(yehao <319)
queue.push_back(yehao+1); //顺序执行下一条指令
while(queue.size() < 320) //一直运行到队列中的个数等于320
{
yehao = getRandNum(yehao); //跳转到m1属于[0,m-1]
queue.push_back(yehao); //将m1插入队列
if(yehao < 319)
queue.push_back(yehao+1); //将m1+1插入队列
int temp = 320 - (yehao + 2);
yehao = yehao+2+getRandNum(temp);//跳转到m2属于[m+2,319]
queue.push_back(yehao); //插入队列
if(yehao < 319)
queue.push_back(yehao+1); //将m2+1插入队列
}
while(queue.size() > 320)
//如果队列中的个数大于320,则把多余的队列进行出栈的操作
queue.pop_back();
}
void InitMemoryQueue() //初始化页面
{
xianzaiweizhi = 0;
exterPage.clear(); //对外存的页面进行清除
interPage.clear(); //对内存的页面进行清除
for(int i=0;i<32;i++)
{
Cpage temp;
temp.id = i;
temp.staytime = 0; //停留时间和未使用的时间都初始化未0
temp.unusualtime = 0;
exterPage.push_back(temp); //将产生的页面进行入队的操作
}
}
int shuyunageyemian(int cmdId)
//通过强制转换成整数的形式判断指令属于哪个页面 {
return int(cmdId/10);
}
int yemianzhuantai(int PageId,bool sign) //分别在内外存中查找页面存在返回位置不存在返回-1 {
if(sign) //在内存中进行查找
for(int i=0;iinterPage[max].staytime)
//找到在内存中停留时间时间最长
max = i;
return max; //返回停留时间最长的最大值
}
int lru() //LRU算法中查找最久未使用的页面 {
int max = 0;
for(int j=0;jinterPage[max].unusualtime)
//找到最久未被使用的算法
max = j;
return max; //返回未被使用的最大值 }
bool Manage(int count,int PageId) //当内存已经满了需要按照算法调度 {
int status = yemianzhuantai(PageId,false);
//获取执行页面在外存中的索引地址
if(status == -1)
return false;
int targetStatus = 0;
if(count == 0)
targetStatus = fifo(); //根据fifo算法内存中需要交换的位置
else if(count == 1)
targetStatus = lru(); //根据lru算法内存中需要交换的位置
interPage[targetStatus].staytime = 0; //将要交换的内存//页面的停留时间和最近多久未被使用的时间进行初始化为0
interPage[targetStatus].unusualtime = 0;
swap(exterPage[status],interPage[targetStatus]); //内外层中的页面进行交换
return true;
}
void run(int count)
{
while(xianzaiweizhi < 320) //如果现在的位置在合理的范围内
{
for(int i=0;i>flag;
if(flag==1) //先进先出的算法调度
{
cout<<"先进先出的算法调度的缺页率为:"<>flag;
} while (flag==1); //满足此条件,重新做里面的内容 system("PAUSE");
}
实验三 文件系统设计 一、实验目的
通过一个简单多用户文件系统的设计 , 加深理解文件系统的内部功能及内
部实现。
二、实验内容
为 Linux 系统设计一个简单的二级文件系统。要求做到以下几点 :
(1) 可以实现下列几条命令 ( 至少 4 条) ;
login 用户登录
dir 列文件目录
create 创建文件
delete 删除文件
open 打开文件
close 关闭文件
read 读文件
write 写文件
(2) 列目录时要列出文件名、物理地址、保护码和文件长度 ;
(3) 源文件可以进行读写保护。
三(程序流程图
开始
否 选择操作,
是
打开文件 创建文件 删除文件
读文件 写文件
注销
结束
四(部分源程序
1. Read函数
函数功能:从系统文件上读取文件数据到文件缓冲区 函数参数:文件指针,缓冲区地址,需要读出文件的字节数。 函数返回值:若读取成功,返回实际读取的文件数。
Static int Reand( struct File*file, void*buf ,ulong_t numBytes) {
Struct PFAT_file*pfatfile=(struct PFAT_file*) file->fsData;
Struct PFAT_Instance*instance=(struct PAFT_Instance*)
File->mountpoint->fsData;
Ulong_t start=file->filepos;
Ulong_t end=file->filepos+numBytes;
Ulong_t startblock,endblock,curblock;
Ulong_t i;
/*若读的文件长度大于INT_MAX,则返回无效*/ If (numBytes>INT_MAX)
Return EINVALID;
/*确保读取的文件的长度是有效的 ,若读取的位置超出文件范围,则无效*/
If (start>=file->endpos||end>file-endpos||endfilepos,numBytes,file->endpos);
Return EINVALID;
}
/*
检测
工程第三方检测合同工程防雷检测合同植筋拉拔检测方案传感器技术课后答案检测机构通用要求培训
需要读取的数据是否都在文件缓冲区中*/ Startblock=(start % SECTOR_SIZE)/SECTOR_SIZE;
Endblock=round_up_block(end)/SECTOR_SIZE;
/*遍历文件系统,查取需要读取的文件块*/
Curlock=pfatfile->entry->firstblock;
For(i=0;i=stratblock){
Int rc=0;
/*对文件进行互斥锁,确保每次仅有一个进程对文件进行读取*/ Mutex_lock(&pfatfile->lock);
If(!Is_Bit_set(pfatfile->validlockSet,i)){
/*读一个磁盘快到文件数据缓冲区*/
Dubeg("reading file bloock %lu (devic block%lu)\n",i,curblock); Rc=block_read(file->mountpoint->dev,curblock,pfatfile->fileDatecache+i*SECTOR_SIZE);
If(rc==0)
/*置该块的已读标记*/
Set_bit(pfatfile->validblockset,i);
}
Mutex_unlock(&pfatfile->lock); If (rc!=0)
Return rc;
}
/*继续读下一块数据*/
Ulong_t nextblock=instance->fat[curblock]; Curblock=nextblock;
}
/*将缓冲区数据复制到调用读函数的进程缓冲区*/ Memcpy(buf,pfatfile->filedatacache+start,numBytes); Debug("read satisfiled!\n");
Reurn numbytes;
}
2. Write()函数
函数功能:将文件缓冲区的数据些入文件系统 函数参数:文件指针,缓冲区地址,写入文件的字节数。 函数返回值:错误标志EACCESS。
Static int write(struct file *file,void*buf,ulong_t numBytes) /*因为文件系统是只读的,所以不允许写入,直接返回标志*/ Return EACCESS;
}
3. OPEN()函数
函数功能:打开文件系统文件。
函数参数:文件系统加载点指针,路径名,打开方式,文件指针。 Statitc int open(struct mount_point*mountpoint,const char*path,int
mode,struct file **pfile)
{
Int rc=0;
Struct PFAT_instance *instance=(struct PFAT_instance*) Mountpoint->fsdata;
Directoryentry*entry;
Struct PAFT_file *pfatfile=0;
Struct file*file=0;
/*如打开文件系统的方式是写或创建,则拒绝操作*/
If ((mode&(o_WRITE|o_create))!=0) Return EACCESS;
/*查找目录项*/
Entry=lookup(instanse,path); If(entry==0)
Return ENOTFOUND;
/*若打开的不是文件,则拒绝操作*/ If(entry->dircetory)
Return EACCESS;
/*得到文件的指针*/
Pfatfile=Get_PAFT_file(insance,ntry); If(pfatfile==0)
Goto done;
/*创建文件完成*/
File=allocate_file(&s_pfatfileops,0,entry->filesize,pfatfile,0,0);
If(file==0)
Rc=enomem;
Goto done;
}
*pfile=file;
Done:reurn rc;
}
4. lookup()函数
函数功能:在文件系统中查找给定名称的目录项。 函数参数:文件系统实例指针,路径名。
函数返回值:若查找成功则返回路径指针,否则返回0。 Static directoryentry *lookup(struct PFAT_instance*instance,const char
*path)
{
Direcoryentry *rootDir=instance->rootDir; Boosector *fsinfo=&instance->fsinfo;
Int i;
KASSERT(*path=='/'); /*若查找的目录是根目录*/
If(strcmp(path,"/")==0) Return &instance->rootDirentry;
/*跳过目录中的第一个‘/’*/
++path;
/*PAFT是单级目录结构,所以不需要处理层次目录*/ For(i=0;irootdirectorycount;++i){ Directoryentoryentry*entry=&rootdir[i]; If(strcmp(entry->filename,path)==0){
/*若找到给定名字的目录项,则返回目录指针* / Debug("found matching dir entry for %s\n",path); Return entry;
}
/*若没找到给定的目录项,则返回0*/
Return 0;
}
(文件系统只写了部分函数,因为对于我来说,由于知识有限,所以花了很长时间才写了部分函数,我实在是写不下去了,也不会写了。请老师谅解~通过文件系统实验我也深刻感到自己的不足)