OS进程控制实验报告.docx
《OS进程控制实验报告.docx》由会员分享,可在线阅读,更多相关《OS进程控制实验报告.docx(18页珍藏版)》请在冰豆网上搜索。
OS进程控制实验报告
学 号
2016143222
姓名
王娟
实验日期
2018.04.13
实验名称
Windows进程观察与控制
实验目的:
1、熟悉Windows2000/XP中任务管理器的使用。
2、通过任务管理器识别操作系统中的进程和线程的相关信息。
3、掌握利用spy++.exe来察看Windows中各个任务的更详细信息。
4、通过对Windows2000编程,进一步熟悉操作系统的基本概念,较好地理解Windows2000的结构。
实验内容:
1、启动操作系统自带的任务管理器
2、调整任务管理器的“查看”中的相关设置,显示关于进程的以下各项信息
3、从桌面启动办公软件“Word”,在任务管理器中找到该软件的登记,并将其结束掉。
再从任务管理器中分别找到下列程序:
winlogon.exe、lsass.exe、csrss.exe、smss.exe,试着结束它们
4、在任务管理器中找到进程“explorer.exe”,将之结束掉,并将桌面上你打开的所有窗口最小化
5、运行“spy++.exe”应用软件,点击按钮“”,切换到窗口显示栏上,查看窗口信息,并执行菜单项“Spy—Message”,用“FinderTool”查看windows各个窗口
6、点击按钮“”,切换到进程显示栏上,查看进程“explorer.exe”的各项信息
7、注意某些线程前有“+”,如图所示:
,说明二者之间的差异
8、获得进程对象的句柄和优先级。
9、获取系统所有进程的进程号和文件名。
10、运行程序2-1、2-2、2-3
实验原理:
任务管理器WindowsXP的任务管理器提供了用户计算机上正在运行的程序和进程的相关信息,也显示了最常用的量度进程性能的单位。
使用任务管理器,可以打开监视计算机性能的关键指示器,快速查看正在运行的程序的状态,或者终止已停止响应的程序。
也可以使用多个参数评估正在运行的进程的活动,以及查看CPU和内存的使用情况的图形和数据。
1.创建进程的API函数:
CreateProcess()调用的核心参数是可执行文件运行时的文件名及其命令行。
表2_1CreateProcess()函数的参数
参数名称
使用目的
LPCTSTRlpApplivationName
全部或部分地指明包括可执行代码的EXE文件的文件名
LPCTSTRlpCommandLine
向可执行文件发送的参数
LPSECURIITY_ATTRIBUTESlpProcessAttributes
设定进程对象的安全性。
NULL为默认安全性。
LPSECURIITY_ATTRIBUTESlpThreadAttributes
设定其线程对象的安全性。
NULL为默认安全性。
BOOLbInheritHandle
子进程是否继承父进程继承,一般设为FALSE。
DWORDdwCreationFlage
特殊的创建标志(如CREATE_SUSPENDED)的位标记
LPVOIDlpEnvironment
一般为NULL,使子进程能够继承它的父进程正在使用的一组环境字符串。
LPCTSTRlpCurrentDirectory
设置子进程的当前驱动器和目录。
如是NULL,则新进程的工作目录将与生成新进程的应用程序的目录相同。
STARTUPINFOlpStartupInfo
包括新进程的运行配置的详情。
使用时应首先进行初始化。
cb必须初始化为sizeof(STARTUPINFO)
LPPROCESS_INFORMATIONlpProcessInformation
新进程的返回信息。
如新进程和主线程的句柄和ID
其中dwCreationFlags参数中指明系统应该给予新进程什么行为。
经常使用的标志是CREATE_SUSPNDED,告诉主线程立刻暂停。
当准备好时,应该使用ResumeThread()API来启动进程。
另一个常用的标志是CREATE_NEW_CONSOLE,告诉新进程启动自己的控制台窗口,而不是利用父窗口。
这一参数还允许设置进程的优先级,用以向系统指明,相对于系统中所有其他的活动进程来说,给此进程多少CPU时间。
2.正在运行的进程
一个进程拥有至少一个执行线程——主线程,这种进程使用主线程来指示它的存在。
当主线程结束时,调用ExitProcess()API函数,通知系统终止它所拥有的所有正在运行、准备运行或正在挂起的其他线程。
当进程正在运行时,可以查看它的许多特性,其中少数特性也允许加以修改。
常用的API函数有:
GetCurrentProcessId():
用来查看进程标识符(PID);
GetModuleFileName()和GetCommandLine():
可以给运行期环境的信息。
GetGuiResources():
可用来查看进程的GUI资源。
进程的其他性能信息可通过GetProcessIoCounters()、GetProcessPriorityBoost()、GetProcessTimes()和GetProcessWorkingSetSize()API得到。
以上这几个API函数都只需要具有PROCESS_QUERY_INFORMATION访问权限的指向所感兴趣进程的句柄。
GetProcessVersion():
可用于进程信息查询。
GetVersionEx():
可得到系统的版本号。
本实验程序3_6中列出了这两个API函数与的共同作用,可确定运行进程的
3.终止进程
ExitProcess()//可被进程自身调用以正常方式终止运行。
TerminateProcess()//可被外部进程调用后终止某进程,由于关闭时的途径不太正常,有可能引起错误的行为。
实验过程与结果:
2、
3、从桌面启动办公软件“Word”,在任务管理器中找到该软件的登记,并将其结束掉。
再从任务管理器中分别找到下列程序:
winlogon.exe、lsass.exe、csrss.exe、smss.exe,试着结束它们,观察到的反应是图标消失,机器关机,原因是系统必须进程,无法从任务管理器关掉。
4、在任务管理器中找到进程“explorer.exe”,将之结束掉,并将桌面上你打开的所有窗口最小化,看看你的计算机系统起来什么样的变化:
桌面图标、开始任务栏消失,得到的结论是explorer.exe是文件资源管理器,包括桌面和文件管理,删除该程序会导致Windows图形界面无法使用explorer.exe用于管理Windows的图形界面。
5、
6、
7、注意某些线程前有“+”,如图所示:
,说明二者之间的差异是有无子进程,“+”表示有子进程。
8、
(1)获得进程对象的句柄和优先级。
程序1_1确定自己的优先权的简单应用程序
#include
#include
//
voidmain()
{HANDLEhProcessThis=GetCurrentProcess();//从当前进程中提取句柄
DWORDdwPriority=GetPriorityClass(hProcessThis);//请求内核提供该进程的优先权
//SetPriorityClass(hProcessThis,HIGH_PRIORITY_CLASS);
cout<<"Currentprocesspriority:
";
cout<cout<<"REALTIME_PRIORITY_CLASS:
"<cout<<"HIGH_PRIORITY_CLASS:
"<cout<<"NORMAL_PRIORITY_CLASS:
"<cout<<"IDLE_PRIORITY_CLASS:
"<}
1何为进程“句柄”:
句柄实际是一个指针,他指向一块包含具体信息数据的内存,可以当做索引,所以进程句柄是当你要访问该进程时取得的,使用完毕必须释放。
②分析、运行该程序,写出运行结果:
_
_
2修改程序,改变程序的优先级
#include
#include
//
voidmain()
{HANDLEhProcessThis=GetCurrentProcess();//从当前进程中提取句柄
DWORDdwPriority=GetPriorityClass(hProcessThis);//请求内核提供该进程的优先权
SetPriorityClass(hProcessThis,HIGH_PRIORITY_CLASS);
cout<<"Currentprocesspriority:
";
cout<cout<<"REALTIME_PRIORITY_CLASS:
"<cout<<"HIGH_PRIORITY_CLASS:
"<cout<<"NORMAL_PRIORITY_CLASS:
"<cout<<"IDLE_PRIORITY_CLASS:
"<}
9、获取系统所有进程的进程号和文件名。
//程序1_2
#include
#include
#include
voidmain()
{//对当前系统中运行的所有进程拍取“快照”
HANDLEhSnapshot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);//初始化进程入口
PROCESSENTRY32pe;
ZeroMemory(&pe,sizeof(pe));
pe.dwSize=sizeof(pe);
BOOLbMore=Process32First(hSnapshot,&pe);
while(bMore)
{cout<<"ProcessID:
"<"<bMore=Process32Next(hSnapshot,&pe);
}
}
3解释:
何为进程“快照”:
进程快照就是当前系统中正在运行的所有进程列表,一般用CreateToolhelp32Snapshot得到.
4分析、运行该程序,写出运行结果:
5
③修改程序,获取系统所有进程的优先级。
#include
#include
#include
voidmain()
{//对当前系统中运行的所有进程拍取“快照”
HANDLEhSnapshot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);//初始化进程入口
PROCESSENTRY32pe;
ZeroMemory(&pe,sizeof(pe));
pe.dwSize=sizeof(pe);
BOOLbMore=Process32First(hSnapshot,&pe);
while(bMore)
{cout<<"ProcessID:
"<"<bMore=Process32Next(hSnapshot,&pe);
}
HANDLEhProcessThis=GetCurrentProcess();
DWORDdwPriority=GetPriorityClass(hProcessThis);
SetPriorityClass(hProcessThis,HIGH_PRIORITY_CLASS);
cout<<"Currentprocesspriority:
";
cout<cout<<"REALTIME_PRIORITY_CLASS:
"<cout<<"HIGH_PRIORITY_CLASS:
"<cout<<"NORMAL_PRIORITY_CLASS:
"<cout<<"IDLE_PRIORITY_CLASS:
"<}
思考题
1.分析spy++软件中窗口、进程和线程的其它信息。
Spy++工具用来监视系统的进程、线程、窗口和窗口消息。
默认界面可查看所有顶层窗口,展开可显示子窗口。
右键窗口,选择“消息”,可打开该窗口的消息查看窗口。
里面实时显示当前消息。
2.编写程序,获取系统所有进程的优先级。
#include
#include
#include
voidmain()
{//对当前系统中运行的所有进程拍取“快照”
HANDLEhSnapshot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);//初始化进程入口
PROCESSENTRY32pe;
ZeroMemory(&pe,sizeof(pe));
pe.dwSize=sizeof(pe);
BOOLbMore=Process32First(hSnapshot,&pe);
while(bMore)
{cout<<"ProcessID:
"<"<bMore=Process32Next(hSnapshot,&pe);
}
HANDLEhProcessThis=GetCurrentProcess();
DWORDdwPriority=GetPriorityClass(hProcessThis);
SetPriorityClass(hProcessThis,HIGH_PRIORITY_CLASS);
cout<<"Currentprocesspriority:
";
cout<cout<<"REALTIME_PRIORITY_CLASS:
"<cout<<"HIGH_PRIORITY_CLASS:
"<cout<<"NORMAL_PRIORITY_CLASS:
"<cout<<"IDLE_PRIORITY_CLASS:
"<}
程序2_1
#include
#include
usingnamespacestd;
intmain()
{
cout<<"I'mthefatherprocess,running.\n"<LPTSTRlpCommandLine="c:
\\Windows\\notepad.exe";
STARTUPINFOsi;
memset(&si,0,sizeof(si));
si.cb=sizeof(si);
PROCESS_INFORMATIONpi;
//Createachildprocess
inti=CreateProcess(NULL,lpCommandLine,NULL,NULL,FALSE,
NORMAL_PRIORITY_CLASS,NULL,NULL,&si,&pi);
if(i)
{CloseHandle(pi.hThread);
for(inti=0;i<=100;i++)
{cout<<"i="<
Sleep(10);
}
LPDWORDexitcode;
//Pleaserunnoneoreachofthefollowingcommandlines.
//①TerminateProcess(pi.hProcess,0);
//②WaitForSingleObject(pi.hProcess,INFINITE);//等子进程结束后继续运行。
CloseHandle(pi.hProcess);
}
elsecout<<"CreateChildProcessfailed."<cout<<"Fatherprocessisending.\n"<return0;
}
分析并运行该程序,结果为:
_
运行到i=100,并弹出一个记事本
分别运行带标号的语句,并分析其功能。
_
__
____
TerminateProcess(pi.hProcess,0);是终止进程的意思。
WaitForSingleObject(pi.hProcess,INFINITE);等待记事本程序关闭
2.程序2_2
#include
#include
#include
staticLPCTSTRMutexName="sign";
//创建当前进程的克隆进程
voidStartClone()
{
TCHARszFilename[MAX_PATH];
GetModuleFileName(NULL,szFilename,MAX_PATH);
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,
CREATE_NEW_CONSOLE,NULL,NULL,&si,&pi);
if(bCreateOK)
{CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
}
voidParent()
{//创建互斥程序体
HANDLEhMutexSuicide=CreateMutex(
NULL,//安全属性,如果为空,句柄不能被子进程继承。
TRUE,//本线程拥有该互斥体。
MutexName);//互斥体的名字
if(hMutexSuicide!
=NULL)
{
cout<<"Creatingthechildprocess."<StartClone();
Sleep(5000);
cout<<"Tellingthechildprocesstoquit."<ReleaseMutex(hMutexSuicide);
CloseHandle(hMutexSuicide);
}
}
voidChild()
{
HANDLEhMutexSuicide=OpenMutex(
SYNCHRONIZE,//打开用于同步
FALSE,//不需要向下传递
MutexName);//名称
if(hMutexSuicide!
=NULL)
{//报告正在等待指令
cout<<"Childwaitingforsuicideinstructions."<WaitForSingleObject(hMutexSuicide,INFINITE);
//准备好终止,清除句柄
cout<<"Childquiting."<CloseHandle(hMutexSuicide);
}
}
intmain(intargc,char*argv[])
{//决定其行为是父进程还是子进程
if(argc>1&&strcmp(argv[1],"child")==0)Child();
elseParent();
}
分析并运行该程序,结果为:
_________________________________________
_______________________
3.程序2_3各进程消耗在内核模式下的时间百分数。
//proclist项目
#include
#include
#include
//计算进程消耗在内核模式下的时间百分数。
DWORDGetKernelModePercentage(constFILETIME&ftKernel,constFILETIME&ftUser)
{
ULONGLONGqwKernel=(((ULONGLONG)ftKernel.dwHighDateTime)<<32)+
ftKernel.dwLowDateTime;
ULONGLONGqwUser=(((ULONGLONG)ftUser.dwHighDateTime)<<32