操作系统实验一.docx
《操作系统实验一.docx》由会员分享,可在线阅读,更多相关《操作系统实验一.docx(38页珍藏版)》请在冰点文库上搜索。
操作系统实验一
姓名:
贾璐萍
班级:
信息管理与信息系统
学号:
41012238
日期:
2012-10-27
实验一Windows2000进程的“一生”
一、实验题目
Windows2000进程的“一生
二、实验目的
1)通过创建进程、观察正在运行的进程和终止进程的程序设计和调试操作,进一步熟悉操作系统的进程概念,理解Windows2000进程的“一生”。
2)通过阅读和分析实验程序,学习创建进程、观察进程和终止进程的程序设计方法。
三、实验内容
1.1创建进程
1)调试实验3-5中的程序
2)观察并分析程序
1.2正在运行的进程
1)调试实验3-6中的程序
2)观察并分析程序
四、实验过程及结果
1.1
步骤1:
登录进入Windows2000Professional。
步骤2:
在“开始”菜单中单击“程序”-“MicrosoftVisualStudio6.0”–“MicrosoftVisualC++6.0”命令,进入VisualC++窗口。
步骤3:
在工具栏单击“打开”按钮,在“打开”对话框中找到并打开实验源程序3-5.cpp。
步骤4:
单击“Build”菜单中的“Compile3-5.cpp”命令编辑3-5.cpp
步骤5:
编译完成后,单击“Build”菜单中的“Build3-5.exe”命令,建可执行文件。
3-5.exe立
步骤6:
在工具栏单击“ExecuteProgram”(执行程序)按钮,或者按Ctrl
+F5键,或者单击“Build”菜单中的“Execute3-5.exe”命令,执行3-5.exe程序。
步骤7:
按Ctrl+S键可暂停程序的执行,按Ctrl+Pause(Break)键可终止程序的执行。
实验源代码
//proccreate项目
#include
#include
#include
//创建传递过来的进程的克隆过程并赋于其ID值
voidStartClone(intnCloneID)
{
//提取用于当前可执行文件的文件名
TCHARszFilename[MAX_PATH];
:
:
GetModuleFileName(NULL,szFilename,MAX_PATH);
//格式化用于子进程的命令行并通知其EXE文件名和克隆ID
TCHARszCmdLine[MAX_PATH];
:
:
sprintf(szCmdLine,\\%s\d%,szFilename,nCloneID);
//用于子进程的STARTUPINFO结构
STARTUPINFOsi;
:
:
ZeroMemory(reinterpret_cast(&si),sizeof(si));
si.cb=sizeof(si);//必须是本结构的大小
//返回的用于子进程的进程信息
PROCESS_INFORMATIONpi;
//利用同样的可执行文件和命令行创建进程,并赋于其子进程的性质
BOOLbCreateOK=:
:
CreateProcess(
szFilename,//产生这个EXE的应用程序的名称
//告诉其行为像一个子进程的标志szCmdLine,
//缺省的进程安全性NULL,
//缺省的线程安全性NULL,
//不继承句柄FALSE,
//使用新的控制台CREATE_NEW_CONSOLE,
NULL,//新的环境
//当前目录NULL,
//启动信息&si,
//返回的进程信息&pi);
对子进程释放引用//
if(bCreateOK)
{
:
:
CloseHandle(pi.hProcess);
:
:
CloseHandle(pi.hThread);
}
}
intmain(intargc,char*argv[])
{
//确定进程在列表中的位置
intnClone(0);
if(argc>1)
{
//从第二个参数中提取克隆ID
:
:
sscanf(argv[1],%d,&nClone);
}
//显示进程位置
std:
:
cout<<<:
:
GetCurrentProcessId()
<<,CloneID:
<<:
endl;
//检查是否有创建子进程的需要
constintc_nCloneMax=25;
if(nClone{
//发送新进程的命令行和克隆号
StartClone(++nClone);
}
//在终止之前暂停一下(l/2秒)
:
:
Sleep(500);
return0;
}
1.2
步骤1:
在VisualC++窗口的工具栏中单击“打开”按钮,在“打开”对话框中找到并打开实验源程序3-6.cpp。
步骤2:
单击“Build”菜单中的“Compile3-6.cpp”命令,再单击“是”按钮确认。
系统对3-6.cpp进行编译。
步骤3:
编译完成后,单击“Build”菜单中的“Build3-6.exe”命令,建立3-6.exe可执行文件。
程序。
3-6.exe按钮,执行)执行程序(”ExecuteProgram:
在工具栏单击“4步骤
步骤5:
单击Ctrl+Alt+Del键,进入“Windows任务管理器”,在“应用程序”选项卡中右键单击“3-6”任务,在快捷菜单中选择“转到进程”命令。
实验源代码
//version项目
#include
#include
//利用进程和操作系统的版本信息的简单示例
voidmain()
{
//提取这个进程的ID号
DWORDdwIdThis=:
:
GetCurrentProcessId();
//获得这一进程和报告所需的版本,也可以发送0以便指明这一进程
DWORDdwVerReq=:
:
GetProcessVersion(dwIdThis);
WORDwMajorReq=(WORD)(dwVerReq>16);
WORDwMinorReq=(WORD)(dwVerReq&0xffff);
std:
:
cout<<<<,requiresOS:
<<:
endl;
//设置版本信息的数据结构,以便保存操作系统的版本信息
OSVERSIONINFOEXosvix;
:
:
ZeroMemory(&osvix,sizeof(osvix));
osvix.dwOSVersionInfoSize=sizeof(osvix);
//提取版本信息和报告
:
:
GetVersionEx(reinterpret_cast(&osvix));
std:
:
cout<<<:
endl;
系统,则提高其优先权NTS(Windows2000)如果是//
if(osvix.dwPlatformId==VER_PLATFORM_WIN32_NT&&
osvix.dwMajorVersion>=5)
{
//改变优先级
:
:
SetPriorityClass(
:
:
GetCurrentProcess(),//利用这一进程
//改变为high
HIGH_PRIORITY_CLASS);
//报告给用户
std:
:
cout<processishighpriority.<:
endl;
}
}
五、回答问题
1.1
1)(结合背景知识回答)该程序中使用的CreateProcess()API函数,此函数的大多数参数都可取缺省值,但是创建标志参数使用了:
______CREATE-NEW-CONSOLE(CreateProcess()的第六个参数)
在任务栏上产标志,指示新进程分配它自己的控制台,这使得运行示例程序时,main()生许多活动标记。
然后该克隆进程的创建方法关闭传递过来的句柄并返回以便让用户看到其中在关闭程序之前,每一进程的执行主线程暂停一下,函数。
的至少一个窗口。
个核心参数?
本实验程序中设置的各个参CreateProcess())函数有___10_____2数的值是:
_szFilename第一个参数值为:
第二个参数值为:
szCmdLine
第六个参数值为:
FALSE第五个参数值为:
CREATE-NEW-CONSOLE
第十个参数值为:
第九个参数值为:
&si&pi
第三、四、七、八个参数的值都为缺省值。
3)部分程序在VisualC++环境完成编译、链接之后,还可以在Windows2000的“命令提示符”状态下尝试执行该程序,看看与在可视化界面下运行的结果有没有不同?
为什么
1.2
1)分析清单3-6中的程序,简述该程序是如何获得当前的PID和所需的进程版本信息?
答:
首先利用GetCurrentProcessId()获得进程的ID号,再用GetVersionEx()提取定义为OSVERSION结构的osvix变量中的操作系统版本信息。
最后打印出程序所用到的操作系统的版本信息。
2)在本程序中用到了哪些主要WindowsAPI函数?
答:
主要用到的API函数是GetProcessVersion()与GetVersionEx(),这两个函数可确定运行进程的操作系统的版本号。
六、实验总结(包括实验中遇到的问题及解决方法,还存在的问题,通过本次实验学到些什么等)
1)通过创建进程、观察正在运行的进程和终止进程的程序设计和调试操作,进一步熟悉操作系统的进程概念,理解windows2000运行过程
2)初步学习了创建进程、观察进程和终止进程的程序设计方法,加深对进程的理解和记忆。
3)函数之间的作用及意义理解不到,导致其用法不熟悉
实验二、事件对象
一、实验题目
事件对象
二、实验目的
1.回顾系统进程、线程的有关概念,加深对Windows2000线程的理解
2.了解事件对象
API
.通过分析实验程序,了解管理事件对象的3.
4.了解在进程中如何使用事件对象
5.了解父进程创建子进程的程序设计方法
三、实验内容
1.调试实验
(二)中的程序。
2.观察并分析程序。
四、实验过程及结果
步骤1:
登录进入Windows2000Professional。
步骤2:
在“开始”菜单中单击“程序”-“MicrosoftVisualStudio6.0”–“MicrosoftVisualC++6.0”命令,进入VisualC++窗口。
步骤3:
在工具栏单击“打开”按钮,在“打开”对话框中找到并打开实验源程序4-1.cpp
步骤4:
单击“Build”菜单中的“Compile4-1.cpp”命令,并单击“是”按钮确认。
系统对4-1.cpp进行编译。
步骤5:
编译完成后,单击“Build”菜单中的“Build4-1.exe”命令,建立4-1.exe可执行文件。
步骤6:
在工具栏单击“ExecuteProgram”(执行程序)按钮,执行4-1.exe程序。
实验源代码
//event项目
#include
#include
//以下是句柄事件。
实际中很可能使用共享的包含文件来进行通讯
staticLPCTSTRg_szContinueEvent=
w2kdg.EventDemo.event.Continue;
工作(由命令行指定)//本方法只是创建了一个进程的副本,以子进程模式BOOLCreateChild()
{
提取当前可执行文件的文件名//
TCHARszFilename[MAX_PATH];
:
:
GetModuleFileName(NULL,szFilename,MAX_PATH);
//格式化用于子进程的命令行,指明它是一个EXE文件和子进程
TCHARszCmdLine[MAX_PATH];
:
:
sprintf(szCmdLine,\\%s\child,szFilename);
//子进程的启动信息结构
STARTUPINFOsi;
:
:
ZeroMemory(reinterpret_cast(&si),sizeof(si));
si.cb=sizeof(si);//必须是本结构的大小
返回的子进程的进程信息结构//
PROCESS_INFORMATIONpi;
使用同一可执行文件和告诉它是一个子进程的命令行创建进程//
BOOLbCreateOK=:
:
CreateProcess(
生成的可执行文件名szFilename,//
szCmdLine,//指示其行为与子进程一样的标志
NULL,//子进程句柄的安全性
//子线程句柄的安全性NULL,
FALSE,//不继承句柄
//0,特殊的创建标志
//新环境NULL,
//当前目录NULL,
//启动信息结构&si,
返回的进程信息结构//&pi);
//释放对子进程的引用
if(bCreateOK)
{
:
:
CloseHandle(pi.hProcess);
:
:
CloseHandle(pi.hThread);
}
return(bCreateOK);
}
然后等待子进程在返回前向事件发出//下面的方法创建一个事件和一个子进程,信号voidWaitForChild()
{
//createaneweventobjectforthechildprocess
//tousewhenreleasingthisprocess
HANDLEhEventContinue=:
:
CreateEvent(
缺省的安全性,子进程将具有访问权限//NULL,
手工重置事件//TRUE,
初始时是非接受信号状态FALSE,
//
事件名称//g_szContinueEvent);
if(hEventContinue!
=NULL)
{
std:
:
cout<:
endl;
//创建子进程
if(:
:
CreateChild())
{
std:
:
cout<:
endl;
等待,直到子进程发出信号//
std:
:
cout<:
endl;
:
:
WaitForSingleObject(hEventContinue,INFINITE);
:
:
Sleep(1500);
std:
:
cout<<:
endl;
}
//清除句柄
:
:
CloseHandle(hEventContinue);
hEventContinue=INVALID_HANDLE_VALUE;
}
}
//以下方法在子进程模式下被调用,其功能只是向父进程发出终止信号
voidSignalParent()
{
//尝试打开句柄
std:
:
cout<:
endl;
HANDLEhEventContinue=:
:
OpenEvent(
//所要求的最小访问权限EVENT_MODIFY_STATE,
FALSE,
//不是可继承的句柄
//事件名称g_szContinueEvent);
if(hEventContinue!
=NULL)
{
std:
:
cout<:
endl;
}
//清除句柄
:
:
CloseHandle(hEventContinue);
hEventContinue=INVALID_HANDLE_VALUE;
}
intmain(intargc,char*argv[])
{
//检查父进程或是子进程是否启动
if(argc>1&&:
:
strcmp(argv[1],child)==0)
{
//向父进程创建的事件发出信号
:
:
SignalParent();
}
else
{
//创建一个事件并等待子进程发出信号
:
:
Sleep(1500);
std:
:
cout<:
endl;
}
return0;
}
五、回答问题
1.两个Sleep(1500)作用是否一样?
删除它们可以吗?
为什么?
答:
两个Sleep(1500)作用不一样。
第一个Sleep(1500)保证了windows线程之间的切换,不可以删除。
若删除,则不进程可能等不到子进程发送的信号就被释放了;第二个Sleep(1500)起到延时的作用,可以删除。
2.说明WaitForSingleObject()的用法以及其作用
答:
用法:
WaitForSingleObject(hEvent,INFINITE)表示无限等待hEvent信号。
返回值有三个。
一个是wait-abandoneo:
被指定的互斥体对象未被另一个线程释放:
一个是wait-object-o:
被指定的对象已经发送信号;一个是:
wait-timeout:
超时。
作用:
若无信号,则说明另一个线程正在访问缓冲区;若有信号,则本线程可以访问缓冲区,当该函数在返回后会自动把该信号置为无信号的,这样在本线程读写缓冲区时别的线程不会同时访问。
在完成读写操作后,需要调用SetEvent()函数把该信号置为有信号的,以使别的线程有机会访问共享缓冲区。
3.程序中创建一个事件使用了哪一个系统函数?
创建时设置的初始信号状态是什么?
答:
CreateEvent(),初始信号状态是:
非接受信号状态。
.创建一个进程(子进程)使用了哪一个系统函数4.
答:
CreateChild()
5.同步对象传递信号时,为什么直接传递同步对象的句柄就可以了
答:
同一进程中的线程之间共享同一张内核对象表,同一个同步对象的句柄对各线程来说都是有效的,所以传递时只要直接传句柄值就行了。
6.写出程序运行的流程
答:
步1:
检查父进程或是子进程是否启动。
步2:
若父进程启动则父进程等待子进程发送信号;若未启动则创建一个事件后,等待子进程发送信号。
步3:
释放信号
六、实验总结(包括实验中遇到的问题及解决方法,还存在的问题,通过本次实验学到些什么等)
1)了解事件对象、管理事件对象的API及在进程中如何使用事件对象
2)了解父进程创建子进程的程序设计方法
3)对整个程序的分析认识不够
实验三、互斥体对象
一、实验题目
互斥对象
二、实验目的
1.了解互斥体对象。
2.了解在进程中如何使用互斥体对象
三、实验内容
1.调试实验(三)中的程序。
2.观察并分析程序。
四、实验过程及结果
步骤1:
登录进入Windows2000Professional。
”6.0StudioVisualMicrosoft“-:
在“开始”菜单中单击“程序”2步骤.
–“MicrosoftVisualC++6.0”命令,进入VisualC++窗口。
步骤3:
在工具栏单击“打开”按钮,在“打开”对话框中找到并打开实验源程序4-2.cpp
步骤4:
单击“Build”菜单中的“Compile4-2.cpp”命令,并单击“是”按钮确认。
系统对4-2.cpp进行编译。
步骤5:
编译完成后,单击“Build”菜单中的“Build4-2exe”命令,建立4-2.exe可执行文件。
步骤6:
在工具栏单击“ExecuteProgram”(执行程序)按钮,执行4-2.exe程序
实验源代码
//mutex项目
#include
#include
//利用互斥体来保护同时访问的共享资源
classCCountUpDown
{
public:
//创建者创建两个线程来访问共享值
CCountUpDown(intnAccesses):
m_hThreadInc(INVALID_HANDLE_VALUE),
m_hThreadDec(INVALID_HANDLE_VALUE),
m_hMutexValue(INVALID_HANDLE_VALUE),
m_nValue(0),
m_nAccess(nAccesses)
{
//创建互斥体用于访问数值
m_hMutexValue=:
:
CreateMutex(
NULL,//缺省的安全性