操作系统实验报告完全版.docx

上传人:b****3 文档编号:10655151 上传时间:2023-05-27 格式:DOCX 页数:35 大小:315.79KB
下载 相关 举报
操作系统实验报告完全版.docx_第1页
第1页 / 共35页
操作系统实验报告完全版.docx_第2页
第2页 / 共35页
操作系统实验报告完全版.docx_第3页
第3页 / 共35页
操作系统实验报告完全版.docx_第4页
第4页 / 共35页
操作系统实验报告完全版.docx_第5页
第5页 / 共35页
操作系统实验报告完全版.docx_第6页
第6页 / 共35页
操作系统实验报告完全版.docx_第7页
第7页 / 共35页
操作系统实验报告完全版.docx_第8页
第8页 / 共35页
操作系统实验报告完全版.docx_第9页
第9页 / 共35页
操作系统实验报告完全版.docx_第10页
第10页 / 共35页
操作系统实验报告完全版.docx_第11页
第11页 / 共35页
操作系统实验报告完全版.docx_第12页
第12页 / 共35页
操作系统实验报告完全版.docx_第13页
第13页 / 共35页
操作系统实验报告完全版.docx_第14页
第14页 / 共35页
操作系统实验报告完全版.docx_第15页
第15页 / 共35页
操作系统实验报告完全版.docx_第16页
第16页 / 共35页
操作系统实验报告完全版.docx_第17页
第17页 / 共35页
操作系统实验报告完全版.docx_第18页
第18页 / 共35页
操作系统实验报告完全版.docx_第19页
第19页 / 共35页
操作系统实验报告完全版.docx_第20页
第20页 / 共35页
亲,该文档总共35页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

操作系统实验报告完全版.docx

《操作系统实验报告完全版.docx》由会员分享,可在线阅读,更多相关《操作系统实验报告完全版.docx(35页珍藏版)》请在冰点文库上搜索。

操作系统实验报告完全版.docx

操作系统实验报告完全版

 

《计算机操作系统》

实验报告

 

班级:

姓名:

学号:

 

实验一进程控制与描述

一、实验目的

通过对Windows2000编程,进一步熟悉操作系统的基本概念,较好地理解Windows2000的结构。

通过创建进程、观察正在运行的进程和终止进程的程序设计和调试操作,进一步熟悉操作系统的进程概念,理解Windows2000中进程的“一生”。

二、实验环境

硬件环境:

计算机一台,局域网环境;

软件环境:

Windows2000Professional、VisualC++企业版。

三、实验内容和步骤

第一部分:

程序1-1Windows2000的GUI应用程序

Windows2000Professional下的GUI应用程序,使用VisualC++编译器创建一个GUI应用程序,代码中包括了WinMain()方法,该方法GUI类型的应用程序的标准入口点。

#include<>

#pragmacomment(lib,“”)

intAPIENTRYWinMain(HINSTANCE/*hInstance*/,

HINSTANCE/*hPrevInstance*/,

LPSTR/*lpCmdLine*/,

int/*nCmdShow*/)

{

:

:

MessageBox(

NULL,

“hello,Windows2000”,

“Greetings”,

MB_OK);

return(0);}

在程序1-1的GUI应用程序中,首先需要头文件,以便获得传送给WinMain()和MessageBox()API函数的数据类型定义。

接着的pragma指令指示编译器/连接器找到库文件并将其与产生的EXE文件连接起来。

这样就可以运行简单的命令行命令CL来创建这一应用程序,如果没有pragma指令,则MessageBox()API函数就成为未定义的了。

这一指令是VisualStudioC++编译器特有的。

接下来是WinMain()方法。

其中有四个由实际的低级入口点传递来的参数。

hInstance参数用来装入与代码相连的图标或位图一类的资源,无论何时,都可用GetModuleHandle()API函数将这些资源提取出来。

系统利用实例句柄来指明代码和初始的数据装在内存的何处。

句柄的数值实际上是EXE文件映像的基地址,通常为0x00400000。

下一个参数hPrevInstance是为向后兼容而设的,现在系统将其设为NULL。

应用程序的命令行(不包括程序的名称)是lpCmdLine参数。

另外,系统利用nCmdShow参数告诉应用程序如何显示它的主窗口(选项包括最小化、最大化和正常)。

最后,程序调用MessageBox()API函数并退出。

如果在进入消息循环之前就结束运行的话,最后必须返回0。

先分析程序功能,再写出运行结果:

操作系统将当前运行的应用程序看作是进程对象。

利用系统提供的惟一的称为句柄(HANDLE)的号码,就可与进程对象交互。

这一号码只对当前进程有效。

在系统中运行的任何进程都可调用GetCurrentProcess()API函数,此函数可返回标识进程本身的句柄。

然后就可在Windows需要该进程的有关情况时,利用这一句柄来提供。

程序1-2:

获得和使用进程的句柄

#include<>

#include

voidmain()

{

HANDLEhProcessThis=:

:

GetCurrentProcess();

DWORDdwPriority=:

:

GetPriorityClass(hProcessThis);

std:

:

cout<<“Currentprocesspriority:

”;

switch(dwPriority)

{

caseHIGH_PRIORITY_CLASS:

std:

:

cout<<“High”;

break;

caseNORMAL_PRIORITY_CLASS:

std :

:

cout<< “Normal”;

break;

caseIDLE_PRIORITY_CLASS:

std:

:

cout<<“Idle”;

break;

caseREALTIME_PRIORITY_CLASS:

std:

:

cout<<“Realtime”;

break;

default:

std:

:

cout<<“”;

break;

}

std:

:

cout<

:

endl;

}

程序1-2中列出的是一种获得进程句柄的方法。

对于进程句柄可进行的惟一有用的操作是在API调用时,将其作为参数传送给系统,正如程序1-2中对GetPriorityClass()API函数的调用那样。

在这种情况下,系统向进程对象内“窥视”,以决定其优先级,然后将此优先级返回给应用程序。

OpenProcess()和CreateProcess()API函数也可以用于提取进程句柄。

前者提取的是已经存在的进程的句柄,而后者创建一个新进程,并将其句柄提供出来。

先分析程序功能,再写出运行结果:

程序1-3显示如何找出系统中正在运行的所有进程,如何利用OpenProcess()API函数来获得每一个访问进程的进一步信息。

程序1-3利用句柄查出进程的详细信息

__________NULL__________________________;

d.___________NULL________________________;

e.___________FALSE____;

f.__________CREATENEWCONSOLE________;

g.__________szCmdLine_________________________;

h.__________NULL__________________________;

i.___________&si________________________;

j.___________&pi____;

程序运行时屏幕显示的信息是:

*(此图是最后出现的一个图,在此之前连续出现几个图。

1、正在运行的进程.

使用进程和操作系统的版本信息

<<<

:

endl;

if==VER_PLATFORM_WIN32_NT&&

>=5)

{

:

:

SetPriorityClass(

:

:

GetCurrentProcess(),

HIGH_PRIORITY_CLASS);

std:

:

cout<<“TaskManagershouldnownowindicatethis”

“processishighpriority.”<

:

endl;

}

}

分析程序,写出运行结果:

当前PID信息:

_______1492______________________________________________

当前操作系统版本:

___RunningonOS:

系统提示信息:

TaskManagershouldnowindiatethisprocessishighpriority.

_______________________________________________________________________

程序向读者表明了如何获得当前的PID和所需的进程版本信息。

为了运行这一程序,系统处理了所有的版本不兼容问题。

接着,程序演示了如何使用GetVersionEx()API函数来提取OSVERSIONINFOEX结构。

这一数据块中包括了操作系统的版本信息。

其中,“OS:

”表示当前运行的操作系统是:

____Windows2000_当前版本为_OS:

最后一段程序利用了操作系统的版本信息,以确认运行的是Windows2000。

代码接着将当前进程的优先级提高到比正常级别高。

单击Ctrl+Alt+Del键,进入“Windows任务管理器”,在“应用程序”选项卡中右键单击本任务,在快捷菜单中选择“转到进程”命令。

在“Windows任务管理器”的“进程”选项卡中,与本任务对应的进程映像名称是(为什么):

_________

右键单击该进程名,在快捷菜单中选择“设置优先级”命令,可以调整该进程的优先级,如设置为“高”后重新运行程序,屏幕显示有变化吗为什么

_____屏幕显示有变化。

ProcessID值由1492变为:

3152________________

2、终止进程

指令其子进程来“杀掉”自己的父进程

<

:

endl;

:

:

StartClone();

:

:

Sleep(5000);

std:

:

cout<<“Tellingthechildprocesstoquit.”<

:

endl;

:

:

ReleaseMutex(hMutexSuicide);

:

:

CloseHandle(hMutexSuicide);}

}

voidChild()

{”<

:

endl;

:

:

WaitForSingleObject(hMutexSuicide,INFINITE);

std:

:

cout<<“Childquiting.”<

:

endl;

:

:

CloseHandle(hMutexSuicide);

}}

intmain(intargc,char*argv[])

{

if(argc>1&&:

:

strcmp(argv[1],“child”)==0)

{Child();}

else

{Parent();}

return0;

}

程序说明了一个进程从“生”到“死”的整个一生。

第一次执行时,它创建一个子进程,其行为如同“父亲”。

在创建子进程之前,先创建一个互斥的内核对象,其行为对于子进程来说,如同一个“自杀弹”。

当创建子进程时,就打开了互斥体并在其他线程中进行别的处理工作,同时等待着父进程使用ReleaseMutex()API发出“死亡”信号。

然后用Sleep()API调用来模拟父进程处理其他工作,等完成时,指令子进程终止。

当调用ExitProcess()时要小心,进程中的所有线程都被立刻通知停止。

在设计应用程序时,必须让主线程在正常的C++运行期关闭(这是由编译器提供的缺省行为)之后来调用这一函数。

当它转向受信状态时,通常可创建一个每个活动线程都可等待和停止的终止事件。

在正常的终止操作中,进程的每个工作线程都要终止,由主线程调用ExitProcess()。

接着,管理层对进程增加的所有对象释放引用,并将用GetExitCodeProcess()建立的退出代码从STILL_ACTIVE改变为在ExitProcess()调用中返回的值。

最后,主线程对象也如同进程对象一样转变为受信状态。

等到所有打开的句柄都关闭之后,管理层的对象管理器才销毁进程对象本身。

还没有一种函数可取得终止后的进程对象为其参数,从而使其“复活”。

当进程对象引用一个终止了的对象时,有好几个API函数仍然是有用的。

进程可使用退出代码将终止方式通知给调用GetExitCodeProcess()的其他进程。

同时,GetProcessTimes()API函数可向主调者显示进程的终止时间。

先分析程序功能,再写出运行结果:

1)_第一次执行时,它创建一个子进程,其行为如同“父亲”。

表示:

_Creatingthechildprocess.

2)______用Sleep()API调用来模拟父进程处理其他工作,等完成时,指令子进程终止。

表示:

Tellingthechildprocesstoquit

在熟悉源代码的基础上,利用本实验介绍的API函数来尝试改进本程序(例如使用GetProcessTimes()API函数)并运行。

请描述你所做的工作:

____GetProcessTimes()API可向主调者显示进程终止时间___________________

_

四、实验总结

进程具有的特征:

结构特征、动态性、并发性、独立性和异步性。

对于进程的定义可以从不同的角度来说,其中较为典型的定义有:

(1)进程是程序的一次执行

(2)进程是一个程序及其数据在处理机上顺序执行时发生的活动

(3)进程是程序在一个数据集合上运行的过程,它是系统进行资源分配和调度的一个独立单位。

对于传统os中的进程定义为:

进程是进程实体的运行过程,使系统进行资源分配和调度的一个独立单位。

进程有三种基本状态:

就绪状态、执行状态、阻塞状态。

创建一个进程:

(1)、申请空白的PCB

(2)为进城分配资源

(3)初始化进程控制块

(4)将进程插入就绪队列

终止一个进程:

(1)根据被终止进程的标识符,从PCB集合中检索出该进程的PCB,从中读出该进程的状态

(2)若终止进程正处于执行状态,应立即中止该进程的执行,并置调度标志为真,用于

指示该进程被终止进程的后应该重新进行调度

(3)若该进程还有子孙进程,还应该将其所有的子孙进程终止,以防止他们成为不可控的进程

(4)将终止进程所拥有的全部资源,或者归还给其父进程,或者归还给系统

(5)将终止进程PCB从所在队列中移除,等待其他程序来搜索信

通过实验更清楚的了解了进程,理解了进程的创建过程和终止过程

 

实验二并发与调度

一、实验目的

在本实验中,通过对事件和互斥体对象的了解,来加深对Windows2000线程同步的理解。

通过分析实验程序,了解管理事件对象的API。

了解在进程中如何使用事件对象,在进程中如何使用互斥体对象,线程如何通过文件映射对象发送数据。

在LinuxRedhat操作系统平台上,用pipe()创建一个管道文件,然后用fork()创建两个生产进程和两个消费进程,它们之间通过pipe()传递消息。

二、实验环境

硬件环境:

计算机一台,局域网环境;

软件环境:

Windows2000Professional,LinuxRedhat操作系统平台,VisualC++企业版。

三、实验内容和步骤

第一部分:

互斥体对象

本程序中显示的类CCountUpDown使用了一个互斥体来保证对两个线程间单一数值的访问。

每个线程都企图获得控制权来改变该数值,然后将该数值写入输出流中。

创建者实际上创建的是互斥体对象,计数方法执行等待并释放,为的是共同使用互斥体所需的资源(因而也就是共享资源)。

利用互斥体保护共享资源

.(低32位)

0);.(低32位)

NULL);.(低32位)

0);."<

:

endl;

:

:

WaitForSingleObject(hThread,INFINITE);

}

:

:

Sleep(500);

__MapViewOfFile()

b.___UnmapViewOfFile(pData)__________________________________________

3)运行时,程序首先通过(CreateFileMapping())函数创建一个小型的文件映射对象(hMapping),接着,使用系统API函数(g_hMutexMapping)再创建一个保护其应用的互斥体(CreateMutex())。

然后,应用程序创建100个线程,每个都允许进行同样的进程,即:

通过互斥体获得访问权,这个操作是由语句:

_for(intnTotal=100;nTotal>0;--nTotal)

{

.(低32位)

0);

hread_request[k]=-1;

Thread_Info[j].n_request=0;

}

erial;

inFile>>Thread_Info[n_Thread].entity;

inFile>>Thread_Info[n_Thread].delay;

charc;

(c);

while(c!

='\n'&&!

()){

inFile>>Thread_Info[n_Thread].thread_request[Thread_Info[n_Thread].n_request++];

(c);

}

n_Thread++;

}

erial;

charTemp_entity=Thread_Info[j].entity;

doubleTemp_delay=Thread_Info[j].delay;

printf("\nthread%2d%c%f",Temp_serial,Temp_entity,Temp_delay);

intTemp_request=Thread_Info[j].n_request;

for(intk=0;k

printf("%d",Thread_Info[j].thread_request[k]);

cout<

}

printf("\n\n");

ntity=='P')

h_Thread[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(Produce),

&(Thread_Info[i]),0,NULL);

else

h_Thread[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(Consume),

&(Thread_Info[i]),0,NULL);

}

\n");

printf("按任意键返回!

\n");

_getch();

return0;

}

_request;j++)

if(Thread_Info[i].thread_request[j]==req)

returnTRUE;

returnFALSE;

}

n",m_serial);

n",m_serial,ProducePos);

Buffer_Critical[ProducePos]=m_serial;

printf("生产者%2d完成生产过程:

\n",m_serial);

printf("缓冲区[%2d]:

%3d\n",ProducePos,Buffer_Critical[ProducePos]);

rite==1)

printf("将页%d写回磁盘第%d块\n",j,page[j].dnumber);

5、page[j].flag=0;

6、page[lnumber].flag=1;

7、page[lnumber].write=0;

8、page[lnumber].pnumber=page[j].pnumber;

printf("淘汰主存块%2d中的页%2d,从磁盘第%d块中调入页%2d\n",

9、page[j].pnumber10、j11、page[lnumber].dnumber12、lnumber);

);

}

voidcommand(unsignedladdress,intwrite)

{unsignedpaddress,ad,pnumber,lnumber;

kk:

13、lnumber=laddress>>10;

14、ad=laddress&0x3FF;

if(lnumber>=page_length)

{

printf("不存在该页\n");

15、page_interrupt(lnumber);

}

if(page[lnumber].flag==1)

{

16、pnumber=page[lnumber].pnumber;

17、paddress=pnumber<<10|ad;

rite=1;

}

else

{

18、page_interrupt(lnumber);

gotokk;

}

}

main()

{intlnumber,flag,pnumber,write,dnumber;

unsignedladdress;

inti;

printf("输入页表的信息,创建页表(若页号为-1,则结束输入)\n");

printf("输入页号和辅存地址:

");

scanf("%d%d",&lnumber,&dnumber);

i=0;

while(lnumber!

=-1)

{19、page[lnumber].lnumber=lnumber;

20、page[lnumber].dnumber=dnumber;

21、i++;

printf("输入页号和辅存地址:

");

scanf("%d%d",&lnumber,&dnumber);

}

page_length=i;

printf("输入主存块号,主存块数要小于%d,(以-1结束):

",i);

scanf("%d",&pnumber);

m=0;

head=0;

while(pnumber!

=-1)

{if(m<=i)

{

24、p[m]=m;

25、page[m].pnumber=pnumber;

26、page[m].flag=1;

27、m++;

}

Scanf7d",&pnumber);

}

printf("输入指令性质(1-修改,0-不需要,其他-结束程序运行)和逻辑地址:

");

scanf("%d%x",&write,&laddress);

while(write==0||write==1)

{

28、command(laddress,write);

printf("输入指令性质(1-修改,0-不需要,其他-结束程序运行)和逻辑地址:

");

scanf("%d%x",&write,&laddress);

}

}

5、程序运行结果及简要分析

首先,通过键盘依次输入了4个主存块,块号为4,6,8,3,同时,将第0,1,2,3个页面依次调入块4,6,8,3中,将这4个页面的页号相应地存入数组p[0],p[1],p[2],p[3]中,然后再通过键盘依次输入逻辑地址:

23,456,abc,2000,然后分离出逻辑地址高六位的页号和低10位的页内地址,由于前3个逻辑地址对应的页号在主存中,所以将这3个页号对应的主存块号和页内地址合成为物理地址;对于最后1个逻辑地址,由于对应的页号不在主存中,所以要进行缺页处理,采用FIFO算法。

实验总结:

通过本次实验让我明白了许多,做事

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

当前位置:首页 > 自然科学 > 物理

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2