山大操作系统课程设计报告全套.docx

上传人:b****5 文档编号:7505973 上传时间:2023-01-24 格式:DOCX 页数:72 大小:433.95KB
下载 相关 举报
山大操作系统课程设计报告全套.docx_第1页
第1页 / 共72页
山大操作系统课程设计报告全套.docx_第2页
第2页 / 共72页
山大操作系统课程设计报告全套.docx_第3页
第3页 / 共72页
山大操作系统课程设计报告全套.docx_第4页
第4页 / 共72页
山大操作系统课程设计报告全套.docx_第5页
第5页 / 共72页
点击查看更多>>
下载资源
资源描述

山大操作系统课程设计报告全套.docx

《山大操作系统课程设计报告全套.docx》由会员分享,可在线阅读,更多相关《山大操作系统课程设计报告全套.docx(72页珍藏版)》请在冰豆网上搜索。

山大操作系统课程设计报告全套.docx

山大操作系统课程设计报告全套

计算机科学与技术学院实验报告:

3

 

实验题目:

信号量同步问题

日期:

2010-11-10

姓名:

实验目的:

在本次实验中,通过使用信号量,在原有的程序框架的基础上添加关键代码实现生产者/消费者同步问题。

从而深入理解Nachos的信号量的使用以及实现,生产者/消费者问题是如何用信号量实现的以及

在Nachos中是如何创建线程,实现多线程。

硬件环境:

 

软件环境:

Linux

实验步骤:

1.首先初始化三个信号量,代码如下:

mutex=newSemaphore("mutux",1);信号量初始化为1,才能起到加锁功能

nfull=newSemaphore("full",0);nfull的大小在生产者没生产前为0

nempty=newSemaphore("empty",BUFF_SIZE);nempty的大小应该为buffer的大小

2.首先考虑生产者进程,首先要查看buffer是否有空,nempty->P();ifnempty>0,nempty=nempty-1,当对缓冲区操作时必须要加锁:

mutex->P();加锁.

然后向ring中放入message信息,其次还要解锁mutex->V();解锁.最后通知消费者buffer有新信息,nfull->V();nfull=nfull+1;具体实现代码如下:

3.考虑消费者进程,像生产者进程一样,查看buffer中是否有信息

nfull->P();ifnfull>0,nfull-1;取消息时也要上锁,即:

mutex->P();加锁.

然后从ringbuffer中取出信息;其次mutex->V();解锁;最后通知生产者bufferr有空nempty->V();nempty=nempty+1,具体代码如下:

4.创建线程生成一个生产者的代码:

producers[i]=newThread(prod_names[i]);

producers[i]->Fork(Producer,i);

4.创建线程生成一个消费者的代码:

producers[i]=newThread(prod_names[i]);

producers[i]->Fork(Producer,i);

关键代码:

void

Producer(_intwhich)

{

intnum;

slot*message=newslot(0,0);

for(num=0;num

//这是消息创建的代码

message->thread_id=which;

message->value=num;

//p,v操作

nempty->P();

mutex->P();

ring->Put(message);

//p,v操作

mutex->V();

nfull->V();

}

}

void

Consumer(_intwhich)

{

charstr[MAXLEN];

charfname[LINELEN];

intfd;

slot*message=newslot(0,0);

sprintf(fname,"tmp_%d",which);

//createafile.NotethatthisisaUNIXsystemcall.

if((fd=creat(fname,0600))==-1)

{

perror("creat:

filecreatefailed");

Exit

(1);

}

for(;;){

//p,v,操作

nfull->P();

mutex->P();

ring->Get(message);

//p,v,操作

mutex->V();

nempty->V();

 

//formastringtorecordthemessage

sprintf(str,"producerid-->%d;Messagenumber-->%d;\n",

message->thread_id,

message->value);

//把信息写入文件

if(write(fd,str,strlen(str))==-1){

perror("write:

writefailed");

Exit

(1);

}

}

}

 

//----------------------------------------------------------------------

//ProdCons

//初始化信号量以及需要的生产者消费者线程

//----------------------------------------------------------------------

void

ProdCons()

{

inti;

DEBUG('t',"EnteringProdCons");

//初始化信号量,包括一个访问互斥信号量,初值为1;

//一个nempty信号量,初值为缓冲区的大小

//一个nfull的信号量,初值为0

mutex=newSemaphore("mutex",1);

nempty=newSemaphore("nempty",BUFF_SIZE);

nfull=newSemaphore("nfull",0);

 

//新建一个缓冲区

ring=newRing(BUFF_SIZE+1);

 

//createandforkN_PRODofproducerthreads

for(i=0;i

{

//thisstatemetistoformastringtobeusedasthenamefor

//produderi.

sprintf(prod_names[i],"producer_%d",i);

//创建生产者线程

producers[i]=newThread(prod_names[i]);

producers[i]->Fork(Producer,i);

};

//createandforkN_CONSofconsumerthreads

for(i=0;i

{

//thisstatemetistoformastringtobeusedasthenamefor

//consumeri.

sprintf(cons_names[i],"consumer_%d",i);

//创建消费者线程

consumers[i]=newThread(cons_names[i]);

consumers[i]->Fork(Consumer,i);

};

}

调试记录:

在源代码中exit(0)没有大写,调试过程发现了这个问题改正,

在使用Linux系统调用写入文件时,有一个头文件没有引入,因而需要修改

#include

#include"copyright.h"

#include"system.h"

#include

#include

而且对于新添加的头文件的方法其中源文件使用的一个方法是废弃的,所以改成相应的方法write(fd,str,strlen(str)),

实验结果:

生成两个文件分别代表两个消费者取得的产品的记录。

文件tmp_0

producerid-->0;Messagenumber-->3;

文件tmp_1

producerid-->0;Messagenumber-->0;

producerid-->1;Messagenumber-->0;

producerid-->1;Messagenumber-->1;

producerid-->0;Messagenumber-->1;

producerid-->0;Messagenumber-->2;

producerid-->1;Messagenumber-->2;

producerid-->1;Messagenumber-->3;

分析结果:

从实验结果中可以看出,两个消费者取得的产品的顺序和生成者生产的顺序是一致的。

结果正确。

(实验所在目录:

home/lu/csc2404/nachos-3.4/code/lab3)

结论分析与体会:

在本次实验中,实现生产者/消费者同步问题,通过使用信号量,即Nachos提供的系统调用,进一步理解Nachos的信号量的使用以及实现

同时,学会在Nachos中是如何创建线程,实现多线程,理解了多线程的问题。

计算机科学与技术学院实验报告:

5

 

实验题目:

扩展Nachos的文件系统

学号:

200800130090

日期:

2010-11-10

姓名:

陆思思

Email:

实验目的:

Nachos的文件系统的文件的大小是不可扩展的:

文件被创建后,文件的大小就不能再改变。

本次实验的目的即是设计扩展Nachos的文件系统,使得文件的大小是可以被扩展的。

这样就可以实现在一个文件尾部或者中间追加文件。

硬件环境:

 

软件环境:

Linux操作系统,Nachos操作系统

实验步骤:

1,了解Nachos文件系统的结构,为一级目录结构,

其中目录结构以及目录的使用记录保存在文件中。

使用BitMap来获取空闲的扇区号。

classDirectoryEntry{

public:

boolinUse;//Isthisdirectoryentryinuse?

intsector;//Locationondisktofindthe

//FileHeaderforthisfile

charname[FileNameMaxLen+1];//Textnameforfile,with+1for

//thetrailing'\0'

};

这个是DirectoryEntry类,也就是目录项。

Directory:

:

Directory(intsize)

{

table=newDirectoryEntry[size];

tableSize=size;

for(inti=0;i

table[i].inUse=FALSE;

}

这个是目录类,也就是一级目录结构的定义。

bool

Directory:

:

Add(char*name,intnewSector)

{

if(FindIndex(name)!

=-1)

returnFALSE;

for(inti=0;i

if(!

table[i].inUse){

table[i].inUse=TRUE;

strncpy(table[i].name,name,FileNameMaxLen);

table[i].sector=newSector;

returnTRUE;

}

returnFALSE;//nospace.Fixwhenwehaveextensiblefiles.

}

这个是添加一个目录项的方法,当创建一个新文件的时候使用。

bool

FileSystem:

:

Create(char*name,intinitialSize)

这个是创建一个新的文件,其中主要工作是新建一个FileHeader,

作为一个目录项中保存的intsector;

FileHeader,即文件头,中保存了这个文件的大小,所占的扇区的数目,

以及所占用的全部的扇区号。

即:

intnumBytes;//Numberofbytesinthefile

intnumSectors;//Numberofdatasectorsinthefile

intdataSectors[NumDirect];//Disksectornumbersforeachdata

//blockinthefile

因此,为了实现对文件的追加工作,首先对FileHeader类里面加入新的方法

boolAppSectors(BitMap*freeMap,intfileSize);,为了改变一个文件的文件头的大小。

2,实现在一个已有的文件尾部追加新的内容。

首先写改变文件头中对文件所在扇区的描述,

由AppSectors来实现;该方法将在OpenFile类的对象执行AppendFile时被调用。

对FileHeader类里面加入新的方法

boolAppSectors(BitMap*freeMap,intfileSize);

bool

FileHeader:

:

AppSectors(BitMap*freeMap,intappFileSize)

{

//如果要追加的文件大小小于等于0,则直接函数返回

if(appFileSize<=0)returntrue;

intrestFileSize=SectorSize*numSectors-numBytes;

/*如果要追加的文件的大小小于一个扇区的文件头可以表示的文件的大小,

则返回成功追加文件,即TRUE,否则返回FALSE*/

if(restFileSize>=appFileSize)

{

numBytes+=appFileSize;

returntrue;

}

else

{

intneedFileSize=appFileSize-restFileSize;

if(freeMap->NumClear()

returnfalse;

inti=numSectors;

numBytes+=appFileSize;

numSectors+=divRoundUp(needFileSize,SectorSize);

for(;i

dataSectors[i]=freeMap->Find();

returntrue;

}

printf("Thefileheaderseefilesize%d\n",FileLength());

}

3,

在openfile.cc文件中,OpenFile类中加入方法,用于追加文件的AppFileSize(intnumByte)。

这个方法首先从文件系统中获取空闲的扇区的位试图文件,构造BitMap对象,

传给FileHeader类的对象(也就是这个OpenFile的文件头),

执行AppSectors(BitMap*freeMap,intfileSize)方法,扩大文件的长度。

bool

OpenFile:

:

AppFileSize(intnumBytes)

{

//fetchthebitmap

OpenFile*freeMapFile=newOpenFile(FreeMapSector);

BitMap*freeMap=newBitMap(NumSectors);

freeMap->FetchFrom(freeMapFile);

//askfornewspace

if(!

(hdr->AppSectors(freeMap,numBytes)))returnfalse;

 

printf("openFileseefilesize%d\n",Length());

//writebackthebitmap

freeMap->WriteBack(freeMapFile);

deletefreeMapFile;

deletefreeMap;

returntrue;

}

4,

在fstest.cc文件中的修改Append方法,也就是在Nachos运行的时候执行命令,

例如:

Nachos–xap../test/smallsmall

这个方法是Nachos系统中本来就提供好的一个方法,只需要在局部修改一下语句,

就可以正确的运行。

void

Append(char*from,char*to,inthalf)

{

/*fileLength是计算出来的Linux文件中的文件的大小

fileLengthBefore是指追加之前的Nachos系统的文件的大小

start是文件开始追加的位置

*/

FILE*fp;

OpenFile*openFile;

intamountRead,fileLength;

char*buffer;

//startpositionforappending

intstart;

 

//OpenUNIXfile

if((fp=fopen(from,"r"))==NULL){

printf("Copy:

couldn'topeninputfile%s\n",from);

return;

}

//FigureoutlengthofUNIXfile

fseek(fp,0,2);

fileLength=ftell(fp);

fseek(fp,0,0);

 

if(fileLength==0)

{

printf("Append:

nothingtoappendfromfile%s\n",from);

return;

}

if((openFile=fileSystem->Open(to))==NULL)

{

//file"to"doesnotexits,thencreateone

if(!

fileSystem->Create(to,0))

{

printf("Append:

couldn'tcreatethefile%stoappend\n",to);

fclose(fp);

return;

}

openFile=fileSystem->Open(to);

}

intfileLengthBefore=openFile->Length();

/*执行追加,并判断要追加文件的大小是否超过最大长度*/

if(!

(openFile->AppFileSize(fileLength)))

{

printf("Theappendingfileistoobig!

\nAppendingfilefailed\n");

//toolongfiletoappend

 

return;

}

ASSERT(openFile!

=NULL);

//appendfromposition"start"

start=openFile->Length()-fileLengthBefore;

printf("valueofstart%d\n",start);

if(half)start=start/2;//如果是从文件的中部追加

openFile->Seek(start);

//AppendthedatainTransferSizechunks

buffer=newchar[TransferSize];

while((amountRead=fread(buffer,sizeof(char),TransferSize,fp))>0)

{

intresult;

printf("startvalue:

%d,amountRead%d,",start,amountRead);

result=openFile->WriteAt(buffer,amountRead,start);

printf("resultofwrite:

%d\n",result);

start+=amountRead;

}

delete[]buffer;

//Writetheinodebacktothedisk,becausewehavechangedit

//需要把该文件的文件头写回磁盘

openFile->WriteBack(to);

printf("inodeshavebeenwrittenback\n");

//ClosetheUNIXandtheNachosfiles

deleteopenFile;

fclose(fp);

}

5,

运行结果:

首先执行./nachos–f,格式化Nachos磁盘

lu@ubuntu:

~/csc2404/nachos-3.4/code/appfilesys$./nachos-f

Nothreadsreadyorrunnable,andnopendinginterrupts.

Assumingtheprogramcompleted.

Machinehalting!

Ticks:

total82600,idle82350,system250,user0

DiskI/O:

reads3,writes5

ConsoleI/O:

reads0,writes0

Paging:

faults0

NetworkI/O:

packetsreceived0,sent0

Cleaningup...

然后执行追加文件的操作:

./nachos-aptest/smallsmall

lu@ubuntu:

~/csc2404/nachos-3.4/code/appfilesys$./nachos-aptest/smallsmall

openFileseefilesize38

valueofstart38

startvalue:

38,amountRead10,resultofwrite:

0

startvalue:

48,amountRead10,resultofwrite:

0

startvalue:

58,amountRead10,resultofwrite:

0

startvalue:

68,amountRead

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > PPT模板 > 商务科技

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1