西电操作系统大作业Word下载.docx
《西电操作系统大作业Word下载.docx》由会员分享,可在线阅读,更多相关《西电操作系统大作业Word下载.docx(17页珍藏版)》请在冰豆网上搜索。
![西电操作系统大作业Word下载.docx](https://file1.bdocx.com/fileroot1/2023-2/5/630a8f4f-00b2-4d67-9f7e-a9d74f505df6/630a8f4f-00b2-4d67-9f7e-a9d74f505df61.gif)
DWORDGetKernelModePercentage(constFILETIME&
ftKernel,constFILETIME&
ftUser)
{
//将FILETIME结构转化为64位整数
ULONGLONGqwKernel=(((ULONGLONG)ftKernel.dwHighDateTime)<
<
32)+ftKernel.dwLowDateTime;
ULONGLONGqwUser=(((ULONGLONG)ftUser.dwHighDateTime)<
32)+ftUser.dwLowDateTime;
//将消耗时间相加,然后计算消耗在内核模式下的时间百分比
ULONGLONGqwTotal=qwKernel+qwUser;
DWORDdwPct=(DWORD)(((ULONGLONG)100*qwKernel)/qwTotal);
return(dwPct);
}
//以下是将当前运行进程名和消耗在内核模式下的时间百分数都显示出来的应用程序
voidmain()
//对当前系统中运行的进程拍取"
快照"
HANDLEhSnapshot=:
:
CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,//提取当前进程
0);
//如果是当前进程,就将其忽略
//初始化进程入口
PROCESSENTRY32pe;
:
ZeroMemory(&
pe,sizeof(pe));
pe.dwSize=sizeof(pe);
//按所有进程循环
BOOLbMore=:
Process32First(hSnapshot,&
pe);
while(bMore)
{
//打开用于读取的进程
HANDLEhProcess=:
OpenProcess(
PROCESS_QUERY_INFORMATION,//指明要得到的信息
FALSE,//不必继承这一句柄
pe.th32ProcessID);
//要打开的进程
if(hProcess!
=NULL)
{
DWORDdwPriority=:
GetPriorityClass(hProcess);
//消除句柄
CloseHandle(hProcess);
std:
cout<
"
\n进程名称:
"
left<
setw(20)<
pe.szExeFile<
进程ID:
setw(10)<
pe.th32ProcessID<
进程优先权:
setw(10);
//打印进程名称、ID及优先权
switch(dwPriority)
{
caseHIGH_PRIORITY_CLASS:
std:
cout<
High"
;
break;
caseNORMAL_PRIORITY_CLASS:
Normal"
caseIDLE_PRIORITY_CLASS:
Idle"
caseREALTIME_PRIORITY_CLASS:
Realtime"
default:
unknown>
}
std:
endl;
}
//转向下一个进程
bMore=:
Process32Next(hSnapshot,&
}
5、实验结果及结果分析
实验结果如下图所示:
结果分析:
实验结果符合实际情况,实验成功。
附录
实验环境:
windows7旗舰版VisualC++6.0环境
实验二
1、实验目的
进程压力测试
1、用循环的办法产生所要求的进程(线程),循环的退出条件是不能产生进程时,即CreateProcess()返回0时,统计产生的进程(线程)数目;
2、子进程的运行方式分别考虑:
子进程挂起或睡眠,挂起操作在父进程通过CREATE_SUSPENDED选项完成;
子进程死循环,即父进程产生子进程后子进程立即执行,并且执行一个死循环;
3、在进程被赋予不同的优先级情况下的结果。
GetModuleFileName():
提取用于当前可执行文件的文件名
GetCurrentProcessId():
获取当前进程一个唯一的标识符
//proccreate项目
stdio.h>
//创建传递过来的进程的克隆过程并赋于其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<
void*>
(&
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:
ProcessID:
<
GetCurrentProcessId()
<
CloneID:
nClone
endl;
//检查是否有创建子进程的需要
constintc_nCloneMax=50;
if(nClone<
c_nCloneMax)
//发送新进程的命令行和克隆号
StartClone(++nClone);
//在终止之前暂停一下(l/2秒)
Sleep(500);
return0;
实验结果:
死循环进行中
死循环进行前后CPU使用情况
由实验结果知,压力测试前后CPU使用情况变化很大,压力测试过程中CPU的使用甚至达到峰值,说明大量进程的创建对CPU的消耗很高。
实验三
使用互斥对象实现线程同步
两个线程对同一个变量进行访问,其中一个线程对变量做加1操作,一个线程对其做减1操作。
改变其数值后将该数值写入输出流中。
通过CreateMutex创建互斥对象,然后利用同一互斥对象,在某一时刻只能被一个线程所访问来实现线程之间的同步性。
ReleaseMutex():
释放由线程拥有的一个互斥体
GetCurrentThreadId():
获取当前线程一个唯一的线程标识符
WaitForSingleObject():
使线程进入等待状态
CreateMutex():
创建互斥对象
//mutex项目
//利用互斥体来保护同时访问的共享资源
classCCountUpDown
public:
//创建者创建两个线程来访问共享值
CCountUpDown(intnAccesses)
/*m_hThreadlnc(INVALID_HANDLE_VALUE),
m_hThreadDec(INVALID_HANDLE_VALUE),
m_hMutexValue(INVALID_HANDLE_VALUE),
*/m_nValue=0;
m_nAccess=nAccesses;
//创建互斥体用于访问数值
m_hMutexValue=:
CreateMutex(
NULL,//缺省的安全性
TRUE,//初始时拥有,在所有的初始化结束时将释放
NULL);
//匿名的
m_hThreadInc=:
CreateThread(
0,//缺省堆栈
IncThreadProc,//类线程进程
reinterpret_cast<
LPVOID>
(this),//线程参数
0,//无特殊的标志
//忽略返回的id
m_hThreadDec=:
DecThreadProc,//类线程进程
//允许另一线程获得互斥体
ReleaseMutex(m_hMutexValue);
//解除程序释放对对象的引用
virtual~CCountUpDown()
CloseHandle(m_hThreadInc);
CloseHandle(m_hThreadDec);
CloseHandle(m_hMutexValue);
//简单的等待方法,在两个线程终止之前可暂停主调者
virtualvoidWaitForCompletion()
//确保所有对象都已准备好
if(m_hThreadInc!
=INVALID_HANDLE_VALUE&
&
m_hThreadDec!
=INVALID_HANDLE_VALUE)
//等待两者完成(顺序并不重要)
:
WaitForSingleObject(m_hThreadInc,INFINITE);
WaitForSingleObject(m_hThreadDec,INFINITE);
protected:
//改变共享资源的简单的方法
virtualvoidDoCount(intnStep)
//循环,直到所有的访问都结束为止
while(m_nAccess>
0)
//等待访问数值
WaitForSingleObject(m_hMutexValue,INFINITE);
//改变并显示该值
m_nValue+=nStep;
thread:
GetCurrentThreadId()
<
value:
setw(5)<
m_nValue
access:
m_nAccess<
//发出访问信号并允许线程切换
--m_nAccess;
Sleep(1000);
//使显示速度放慢
//释放对数值的访问
staticDWORDWINAPIIncThreadProc(LPVOIDlpParam)
//将参数解释为'
this'
指针
CCountUpDown*pThis=
CCountUpDown*>
(lpParam);
//调用对象的增加方法并返回一个值
pThis->
DoCount(+1);
return(0);
staticDWORDWINAPIDecThreadProc(LPVOIDlpParam)
reinterpret_cast<
CCountUpDown*>
//调用对象的减少方法并返回一个值
DoCount(-1);
HANDLEm_hThreadInc;
HANDLEm_hThreadDec;
HANDLEm_hMutexValue;
intm_nValue;
intm_nAccess;
};
CCountUpDownud(20);
ud.WaitForCompletion();
实验结果分析:
由实验结果知,线程5428和线程5432交替执行,每次运行之后,数值返回初始值“0”,每次运行之后写入线程在等待队列中变成最后一个,内核保证它在其他线程工作时不会再运行。