操作系统课程设计.docx
《操作系统课程设计.docx》由会员分享,可在线阅读,更多相关《操作系统课程设计.docx(35页珍藏版)》请在冰豆网上搜索。
![操作系统课程设计.docx](https://file1.bdocx.com/fileroot1/2022-11/24/d6cf5da9-b409-4676-a754-59785d5243d9/d6cf5da9-b409-4676-a754-59785d5243d91.gif)
操作系统课程设计
设计1Windows应用程序与DLL
一、设计目的
1、通过编写一个Windows窗口应用程序,了解Windows编程的基本方法,理解Windows操作系统的消息通信机制;
2、通过编写一个动态链接库,体会程序执行时的动态链接过程,掌握DLL的基本原理及其导入与导出。
二、设计要求
1、编写一个Windows应用程序,要求产生一个简单窗口,在该窗口的菜单栏中有一个Menu菜单,其中包含三个菜单项:
Menuq1、Menu2和Exit。
单击Menu1,在窗口的客户区显示“Menu1”;单击了Menu2,在窗口的客户区显示“Menu2”。
单击Exit,退出程序。
2、编写一个DLL,其中含有两个Func1和Func2可供应用程序调用,这两个函数的功能均是返回一个字符串。
3、修改第一项创建的应用程序,使得当单击菜单项Menu1时调用第2项创建的DLL中的Func1,获得Func1返回的字符串,并将其显示在窗口的客户区中。
单击菜单项Menu2时调用Func2,并完成类似的操作。
4、要求使用C编程,不允许使用MFC,以便体会Windows应用程序的消息机制。
要求创建新工程时使用EmptyProject,程序中的所有代码均有自己完成,不用VC++自动生成的代码。
三、设计说明
四、运行结果及分析
1、程序运行后出现一个窗口,单击鼠标时,出现一个消息框。
2、点击菜单项中的Menu1,在窗口中输出menu1,并且调用了DLL中的Func1。
点击菜单项中的Menu2,在窗口中输出menu2,并且调用了DLL中的Func2。
3、点击菜单项中的Exit或关闭按钮,弹出一个消息框,询问是否要退出。
点击“确定”则退出程序,点击“取消”则返回主窗口。
五、总结
1、了解了DLL的基本原理,而且DLL与C++类有所不同。
类是创建时的模块,而DLL是运行时的模块。
2、通过该实验对Windows编程的基本方法和Windows操作系统的消息处理机制有了一定的了解,即以事件驱动为动力的程序运行机制以及将程序代码与用户界面分开处理的程序开发手段。
3、初步接触win32编程方法时有些不适应,因为它是以事件为驱动,与以前所学C编程不同。
但经过对其消息处理机制的了解,对基本的编程方法有了初步的掌握。
附:
主要源代码
1、
LRESULTCALLBACKWindowProc(
HWNDhwnd,
UINTuMsg,
WPARAMwParam,
LPARAMlParam
)
{
HDChdc;
staticPCSTRoutPut="";
PAINTSTRUCTps;
switch(uMsg)
{
caseWM_PAINT:
hdc=BeginPaint(hwnd,&ps);
TextOut(hdc,0,0,"这是一个win32程序",strlen("这是一个win32程序"));
EndPaint(hwnd,&ps);
break;
caseWM_LBUTTONDOWN:
MessageBox(hwnd,"mouse","张晓磊",MB_OK);
hdc=GetDC(hwnd);
TextOut(hdc,0,40,"您单击了鼠标",strlen("您单击了鼠标"));
ReleaseDC(hwnd,hdc);
break;
caseWM_COMMAND:
switch(LOWORD(wParam))
{
caseFILE_MENU1:
hdc=GetDC(hwnd);
outPut=fun1(hInst);//从dll文件里获得字符串
TextOut(hdc,0,80,outPut,strlen(outPut));
TextOut(hdc,0,60,"点击了menu1",strlen("点击了menu1"));
ReleaseDC(hwnd,hdc);
break;
caseFILE_MENU2:
hdc=GetDC(hwnd);
outPut=fun2(hInst);//从dll文件里获得字符串
TextOut(hdc,0,100,outPut,strlen(outPut));
TextOut(hdc,0,120,"点击了menu2",strlen("点击了menu2"));
ReleaseDC(hwnd,hdc);
break;
caseHELP_ABOUT:
MessageBox(hwnd,"这是一个win32测试程序","帮助",MB_OK);
break;
caseFILE_EXIT:
if(IDYES==MessageBox(hwnd,"是否真的要退出?
","!
",MB_YESNO))
DestroyWindow(hwnd);
break;
}
break;
caseWM_CLOSE:
if(IDYES==MessageBox(hwnd,"是否真的要退出?
","!
",MB_YESNO))
DestroyWindow(hwnd);
break;
caseWM_DESTROY:
PostQuitMessage(0);
break;
default:
returnDefWindowProc(hwnd,uMsg,wParam,lParam);
}
return0;
}
2、intWINAPIDllMain(HINSTANCEhinstance,DWORDfdwreason,PVOIDpvreserved)
{
switch(fdwreason)
{
caseDLL_PROCESS_ATTACH:
break;
caseDLL_THREAD_ATTACH:
break;
caseDLL_PROCESS_DETACH:
break;
caseDLL_THREAD_DETACH:
break;
}
returnTRUE;
}
EXPORTPCSTRfun1(HINSTANCEhinstance)
{
PCSTRptr="从fun1中得到dll.位置:
";
strcpy(lpszname,ptr);
intsize=101-strlen(ptr);
char*temp=&lpszname[strlen(ptr)];
GetModuleFileName(hinstance,temp,size);
infor=lpszname;
returninfor;
}
EXPORTPCSTRfun2(HINSTANCEhinstance)
{PCSTRptr="从fun2中得到dll.位置:
";
strcpy(lpszname,ptr);
intsize=101-strlen(ptr);
char*temp=&lpszname[strlen(ptr)];
GetModuleFileName(hinstance,temp,size);
infor=lpszname;
returninfor;}
设计2读者写着问题
一、设计目的
1、熟悉用信号量机制,实现读者优先与写者优先。
理解写者优先、读者优先算法
二、设计要求
在Windows2000环境下,创建一个控制台进程,此进程包含n个线程。
用这n个线程来表示n个读者或写者。
每个线程按相应测试数据文件的要求进行读写操作。
用信号量机制分别实现读者优先和写者优先的读者-写者问题。
三、设计说明
1、读者优先-读者线程的流程图:
2、读者优先-写者线程的流程图
3、写者优先-读者线程:
4、写者优先—写者线程:
四、运行结果及分析
1、建立文件thread.dat,在文件中写入:
1R35
2W45
3R52
4R65
5W5.13
2、程序运行的之后出现一个选择菜单(1:
ReaderPriority2:
WriterPriority3:
ExittoWindows)。
选择读者优先,结果:
选择写者优先,结果:
五、总结
1、学会了互斥对象和临界区对象的使用方法。
2、当一个线程进入临界区后,其它线程若想进入必须等待。
读者优先:
除非有写者在写文件,否则读者不需要等待。
写者优先:
与读者优先类似。
不同之处在于一旦一个写者到来,它应该尽快对文件进行写操作,如果有一个写者在等待,则新到来的读者不允许进行读操作。
附:
主要源代码
1、//读者优先发展——读者线程
//P:
读者线程信息
voidRP_ReaderThread(void*p)
{
//互斥变量
HANDLEh_Mutex;
h_Mutex=OpenMutex(MUTEX_ALL_ACCESS,false,"metux_for_readcount");
DWORDwait_for_mutex;//等待互斥变量所有权
DWORDm_delay;//延迟时间
DWORDm_persist;//读文件持续时间
intm_serial;//线程序号
//从参数中获得信息
m_serial=((ThreadInfo*)(p))->serial;
m_delay=(DWORD)(((ThreadInfo*)(p))->delay*INTE_PER_SEC);
m_persist=(DWORD)(((ThreadInfo*)(p))->persist*INTE_PER_SEC);
Sleep(m_delay);//延迟等待
printf("Readerthread%dsentsthereadingrequire.\n",m_serial);
//等待互斥信号,保证对readcount的访问,修改和互斥
wait_for_mutex=WaitForSingleObject(h_Mutex,-1);
//读者数目增多
readcount++;
if(readcount==1)
{
//第一个读者,等待资源
EnterCriticalSection(&RP_Write);
}
ReleaseMutex(h_Mutex);//释放互斥信号
//读文件
printf("Readerthread%dbeginstoreadfile.\n",m_serial);
Sleep(m_persist);
//退出进程
printf("Readerthread%dfinishedreadingfile.\n",m_serial);
//等待互斥信号,保证对readcount的访问,修改和互斥
wait_for_mutex=WaitForSingleObject(h_Mutex,-1);
//读者数目减少
readcount--;
if(readcount==0)
{
//如果所有读者读完,唤醒写者
LeaveCriticalSection(&RP_Write);
}
ReleaseMutex(h_Mutex);//释放互斥信号
}
//读者优先--写者线程
//p:
写者线程信息
voidRP_WriterThread(void*p)
{
DWORDm_delay;//延迟时间
DWORDm_persist;//写文件持续时间
intm_serial;//线程序号
//从参数中获得信息
m_serial=((ThreadInfo*)(p))->serial;
m_delay=(DWORD)(((ThreadInfo*)(p))->delay*INTE_PER_SEC);
m_persist=(DWORD)(((ThreadInfo*)(p))->persist*INTE_PER_SEC);
Sleep(m_delay);//延迟等待
printf("Writerthread%dsentsthewritingrequire.\n",m_serial);
//等待资源
EnterCriticalSection(&RP_Write);
//写文件
printf("Writerthread%dbeginstowritetothefile.\n",m_serial);
Sleep(m_persist);
//退出进程
printf("Writerthread%dfinishedwritingtothefile.\n",m_serial);
//释放资源
LeaveCriticalSection(&RP_Write);
}
2、//写者优先--读者线程
//p:
读者线程信息
voidWP_ReaderThread(void*p)
{
//互斥变量
HANDLEh_Mutex1;
h_Mutex1=OpenMutex(MUTEX_ALL_ACCESS,false,"metux1");
HANDLEh_Mutex2;
h_Mutex2=OpenMutex(MUTEX_ALL_ACCESS,false,"metux2");
DWORDwait_for_mutex1;//等待互斥变量所有权
DWORDwait_for_mutex2;
DWORDm_delay;//延迟时间
DWORDm_persist;//读文件持续时间
intm_serial;//线程序号
//从参数中获得信息
m_serial=((ThreadInfo*)(p))->serial;
m_delay=(DWORD)(((ThreadInfo*)(p))->delay*INTE_PER_SEC);
m_persist=(DWORD)(((ThreadInfo*)(p))->persist*INTE_PER_SEC);
Sleep(m_delay);//延迟等待
printf("Readerthread%dsentsthereadingrequire.\n",m_serial);
wait_for_mutex1=WaitForSingleObject(h_Mutex1,-1);
//进入读者临界区
EnterCriticalSection(&cs_read);
//阻塞互斥对象mutex2,保证对mutex1的访问、修改互斥
wait_for_mutex2=WaitForSingleObject(h_Mutex2,-1);
//修改读者数目
readcount++;
if(readcount==1)
{
//如果是第一个读者,等待写者写完
EnterCriticalSection(&cs_Write);
}
ReleaseMutex(h_Mutex2);//释放互斥信号Mutex2
//让其他读者进入临界区
LeaveCriticalSection(&cs_read);
ReleaseMutex(h_Mutex1);
//读文件
printf("Readerthread%dbeginstoreadfile.\n",m_serial);
Sleep(m_persist);
//退出进程
printf("Readerthread%dfinishedreadingfile.\n",m_serial);
//阻塞互斥对象mutex2,保证对readcount的访问,修改和互斥
wait_for_mutex2=WaitForSingleObject(h_Mutex2,-1);
readcount--;
if(readcount==0)
{
//最后一个读者,唤醒写者
LeaveCriticalSection(&cs_Write);
}
ReleaseMutex(h_Mutex2);//释放互斥信号
}
//写者优先--写者线程
//p:
写者线程信息
voidWP_WriterThread(void*p)
{
DWORDm_delay;//延迟时间
DWORDm_persist;//写文件持续时间
intm_serial;//线程序号
DWORDwait_for_mutex3;
//互斥对象
HANDLEh_Mutex3;
h_Mutex3=OpenMutex(MUTEX_ALL_ACCESS,false,"metux3");
//从参数中获得信息
m_serial=((ThreadInfo*)(p))->serial;
m_delay=(DWORD)(((ThreadInfo*)(p))->delay*INTE_PER_SEC);
m_persist=(DWORD)(((ThreadInfo*)(p))->persist*INTE_PER_SEC);
Sleep(m_delay);//延迟等待
printf("Writerthread%dsentsthewritingrequire.\n",m_serial);
//阻塞互斥对象mutex3,保证对writecount的访问,修改和互斥
wait_for_mutex3=WaitForSingleObject(h_Mutex3,-1);
writecount++;
if(writecount==1)
{
//第一个写者,等待读者读完
EnterCriticalSection(&cs_read);
}
ReleaseMutex(h_Mutex3);//释放互斥信号Mutex3
//进入写者临界区
EnterCriticalSection(&cs_Write);
//写文件
printf("Writerthread%dbeginstowritetothefile.\n",m_serial);
Sleep(m_persist);
//退出进程
printf("Writerthread%dfinishedwritingtothefile.\n",m_serial);
//离开临界区
LeaveCriticalSection(&cs_Write);
//阻塞互斥对象mutex3,保证对writecount的访问,修改和互斥
wait_for_mutex3=WaitForSingleObject(h_Mutex3,-1);
writecount--;
if(writecount==0)
{
//写者写完,读者可以读
LeaveCriticalSection(&cs_read);
}
ReleaseMutex(h_Mutex3);
}
设计3内存管理
一、设计目的
1、从不同侧面了解Windows2000/xp对用户进程的虚拟内存空间的管理、分配方法。
同时需要了解跟踪程序的编写方法。
2、对Windows分配虚拟内存、改变内存状态,以及对物理内存和页面文件状态查询的API函数的功能、参数限制、使用规则要进一步了解。
二、设计要求
使用Windows2000/xp的API函数,编写一个包含连个线程的进程,一个线程用于模拟内存分配活动,一个线程用于跟踪第一个线程的内存行为,而且要求两个线程之间通过信号量实现同步。
模拟内存活动的线程可以从一个文件中读出妖精性的内存操作,每个内存操作包括如下内容:
1、时间:
操作等待时间。
2、块数:
分配内存的粒度。
3、操作:
包括保留一个区域和加锁与解锁一个区域,可以将这些操作编写存放于文件。
4、大小:
块的大小。
5、访问权限:
可以将权限编号存放于文件中跟踪县城将页面大小、已使用的地址范围、以及内存总量等新型显示出来。
三、设计说明
四、运行结果及分析
1、先编译memory1.cpp生成memory.exe,运行memory1.exe程序,生成openfile文件。
将penfile文件拷贝到memory2.cpp的目录中,编译并运行,可以出现如下结果:
五、总结
1、通过内存分配活动模拟和跟踪的编程实现,从不同侧面了解Windows2000/XP对用户进程虚拟内存的管理,分配方法。
也使自己对课本上所讲的内存管理的知识有了更时刻的理解与认识,从试验结果中更直观的体会到内存的分配方法。
2、对页面文件状态查询的API函数的功能、参数限制、使用规则有了更多地了解。
3、通过本次实验了解了Windows操作系统对虚拟内存的管理与分配方法。
附:
主要源代码
1、//生成openfile文件
#include
#include
#include
#include
structoperation
{
inttime;//起始时间
intblock;//内存页数
intoper;//操作
intprotection;//权限
};
intmain()
{
FILE*file;
file=fopen("opfile","wb");//"opfile"为二进制用以确定内存操作
operationop;
for(intj=0;j<6;j++)//0-保留;1-提交;2-锁;3-解锁;4-回收;5-释放
for(inti=0;i<5;i++)
//0-PAGE_READONLY;
//1-PAGE_READWRITE;
//2-PAGE_EXECUTE;
//3-PAGE_EXECUTE_READ;
//4-PAGE_EXECUTE_READWRITE;
{
op.time=rand()%1000;//随即生成等待时间
op.block=rand()%5+1;//随即生成块大小
op.oper=j;
op.protection=i;
fwrite(&op,sizeof(operation),1,file);//将生成的结构写入文件
}
return0;
}
2、#include
#include
#include
#include
#include
structoperation
{
inttime;//起始时间
intblock;//内存页数
intoper;//操作
intprotection;//权限
};
structtrace//跟踪每一次分配活动的数据结构
{
LPVOIDstart;//起始地址
longsize;//分配的大小
};
HANDLEallo,trac;//信号量句柄
DWOR