您的位置:首页 > 其它

MOOC清华《面向对象程序设计》第6章:负载监视器的设计

2017-09-09 17:30 375 查看
经过了整整一个星期的折腾,负载监视器的设计算是“小功告成”了吧!完成了总体框架设计,采用了黄震春老师所讲的单一责任原则、策略模式,完成了CPU负载率的获得、总内存和已用内存的获得。然而只能算“小功告成”的原因是:黄老师讲的委托模式、GUIDisplay接口的分离,尚未完成,因为如何用GUI显示,我还没学会;另外,在MSDN查了一周的库函数也没有查到能直接获得网络时延的函数或是结构体,后来得知需要自己编一个Ping程序来做,这个我又不会,只得把NetworkLatency这块暂时缺着。待后续学了这方面的知识再来补全。

以下是我的代码:

//main.cpp

#include <iostream>
#include <windows.h>
#include "Monitor.h"
using namespace std;

int main() {
//可直接在这里定义四个对象所属的实现类,以确定底层如何实现,就像下面这四行
//GangliaLoadStrategy loadStrategy;
//WinMemoryStrategy memoryStrategy;
//PingLatencyStrategy latencyStrategy;
//WindowsDisplay display;

LoadStrategyImpl_1 loadStrategy;
MemoryStrategyImpl_1 memoryStrategy;
LatencyStrategyImpl_1 latencyStrategy;
DisplayImpl_1 display;

Monitor monitor(&loadStrategy,
&memoryStrategy,
&latencyStrategy,
&display);

//while(running()){//Windows库函数没有running这一项
while(1){
monitor.getLoad();
monitor.getTotalMemory();
monitor.getUsedMemory();
monitor.getNetworkLatency();

monitor.show();
//for(int i = 0; ; i++) cout << i << endl;//test
Sleep(1000);// S 必须是大写,否则windows.h 不认识
}
return 0;
}

//Monitor.h

#ifndef Monitor_h
#define Monitor_h

#include "LoadStrategy.h"
#include "MemoryStrategy.h"
#include "LatencyStrategy.h"
#include "Display.h"

class Monitor{
public:
Monitor(LoadStrategy *loadStrategy, MemoryStrategy *memoryStrategy,
LatencyStrategy *latencyStrategy, Display *display);
~Monitor();
//构造函数的初始化列表已经确定了四个策略类的具体实现类,而且构造函数集中在一起初始化
//的办法明显更简便,视频中下面的这三行,我认为多余了。
//void setLoadStrategy(LoadStrategy *loadStrategy);
//void setMemoryStrategy(MemoryStrategy *memoryStrategy);
//void setLatencyStrategy(LatencyStrategy *latencyStrategy);

void getLoad();
void getTotalMemory();
void getUsedMemory();
void getNetworkLatency();
void show();

//virtual ~Monitor();

private:
LoadStrategy *m_loadStrategy;
MemoryStrategy *m_memStrategy;
LatencyStrategy *m_latencyStrategy;
Display *m_display;
float load, latency;
long totalMemory, usedMemory;
};

class LoadStrategy;
class LoadStrategyImpl_1;
class LoadStrategyImpl_2;

class MemoryStrategy;
class MemoryStrategyImpl_1;
class MemoryStrategyImpl_2;

class LatencyStrategy;
class LatencyStrategyImpl_1;
class LatencyStrategyImpl_2;

class Display;
class DisplayImpl_1;
class DisplayImpl_2;

#endif

//Monitor.cpp

#include "Monitor.h"
using namespace std;

Monitor::Monitor(LoadStrategy *loadStrategy, MemoryStrategy *memStrategy,
LatencyStrategy *latencyStrategy, Display *display):
m_loadStrategy(loadStrategy), m_memStrategy(memStrategy),
m_latencyStrategy(latencyStrategy), m_display(display),
load(0.0), latency(0.0), totalMemory(0), usedMemory(0){ }

Monitor::~Monitor(){}

void Monitor::getLoad(){
load = m_loadStrategy -> getLoad();
}

void Monitor::getTotalMemory(){
totalMemory = m_memStrategy -> getTotal();
}

void Monitor:: getUsedMemory(){
usedMemory = m_memStrategy -> getUsed();
}

void Monitor::getNetworkLatency(){
latency = m_latencyStrategy -> getLatency();
}

void Monitor::show(){
m_display -> show(load, totalMemory, usedMemory, latency);
}

//LoadStrategy.h

#ifndef LoadStrategy_h
#define LoadStrategy_h

#include <iostream>
#include <windows.h>
using namespace std;

class LoadStrategy{
public:
virtual ~LoadStrategy(){}
virtual float getLoad() = 0;
};

class LoadStrategyImpl_1:public LoadStrategy{
public:
~LoadStrategyImpl_1(){}

__int64 CompareFileTime(FILETIME time1, FILETIME time2);
float getLoad();
};

class LoadStrategyImpl_2:public LoadStrategy{
public:
~LoadStrategyImpl_2(){}

float getLoad(){
//get load here
float load = 0.0;
return load;
}
};

#endif

//LoadStrategy.cpp
#include <iostream>
#include <windows.h>
#include "LoadStrategy.h"
using namespace std;

__int64 LoadStrategyImpl_1::CompareFileTime(FILETIME time1, FILETIME time2)
{
__int64 a = time1.dwHighDateTime << 32 | time1.dwLowDateTime ;
__int64 b = time2.dwHighDateTime << 32 | time2.dwLowDateTime ;
return (b - a);
}

float LoadStrategyImpl_1::getLoad(){
float load = 0.0;
FILETIME idleTime;//空闲时间
FILETIME kernelTime;//核心态时间
FILETIME userTime;//用户态时间

GetSystemTimes(&idleTime, &kernelTime, &userTime );
//这里务必调用GetSystemTimes函数一次

HANDLE hEvent;
FILETIME pre_idleTime;
FILETIME pre_kernelTime;
FILETIME pre_userTime;

pre_idleTime = idleTime;
pre_kernelTime = kernelTime;
pre_userTime = userTime;

hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
//初始值为nonsignaled,并且每次触发后自动设置为nonsignaled

WaitForSingleObject(hEvent, 1000);//等待500毫秒

GetSystemTimes(&idleTime, &kernelTime, &userTime );
//这里务必再调用GetSystemTimes函数一次

__int64 idle = CompareFileTime(pre_idleTime, idleTime);
__int64 kernel = CompareFileTime(pre_kernelTime, kernelTime);
__int64 user = CompareFileTime(pre_userTime, userTime);

load = (kernel + user - idle) * 100.0 / (kernel + user);
//(总的时间 - 空闲时间)/ 总的时间 = 占用CPU时间的比率,即占用率

pre_idleTime = idleTime;
pre_kernelTime = kernelTime;
pre_userTime = userTime;

return load;
}

//MemoryStrategy.h

#ifndef MemoryStrategy_h
#define MemoryStrategy_h

#include <iostream>
using namespace std;

class MemoryStrategy{
public:
virtual ~MemoryStrategy(){}
virtual long getTotal() = 0;
virtual long getUsed() = 0;
};

class MemoryStrategyImpl_1:public MemoryStrategy{
public:
~MemoryStrategyImpl_1(){}

long getTotal();

long getUsed();
};

class MemoryStrategyImpl_2:public MemoryStrategy{
public:
~MemoryStrategyImpl_2(){}

long getTotal(){
//get total memory here
long total = 0;
return total;
}

long getUsed(){
//get used memory here
long used = 0;
return used;
}
};

#endif

//MemoryStrategy.cpp

#include <iostream>
#include <windows.h>
#include "MemoryStrategy.h"
using namespace std;

long MemoryStrategyImpl_1::getTotal(){
//get total memory here
long total = 0;

MEMORYSTATUSEX statex;
statex.dwLength = sizeof (statex);//必须有这一句,否则函数错误!
bool res = GlobalMemoryStatusEx(&statex);

HANDLE hEvent;
hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
//初始值为nonsignaled,并且每次触发后自动设置为nonsignaled

const unsigned long long DIV = 1024;

WaitForSingleObject(hEvent, 1000);//等待500毫秒

total = statex.ullTotalPhys / DIV / DIV ;

return total;
}

long MemoryStrategyImpl_1::getUsed(){
//get used memory here
long used = 0;

MEMORYSTATUSEX statex;
statex.dwLength = sizeof (statex);//必须有这一句,否则函数错误!
bool res = GlobalMemoryStatusEx(&statex);

HANDLE hEvent;
hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
//初始值为nonsignaled,并且每次触发后自动设置为nonsignaled

const unsigned long long DIV = 1024;

WaitForSingleObject(hEvent, 1000);//等待500毫秒

used = statex.ullTotalPhys / DIV / DIV - statex.ullAvailPhys / DIV / DIV ;

return used;
}

//LatencyStrategy.h

#ifndef LatencyStrategy_h
#define LatencyStrategy_h

#include <iostream>
using namespace std;

class LatencyStrategy{
public:

4000
virtual ~LatencyStrategy(){}
virtual float getLatency() = 0;
};

class LatencyStrategyImpl_1:public LatencyStrategy{
public:
~LatencyStrategyImpl_1(){}

float getLatency(){
//get load here
float latency = 0.0;
return latency;
}
};

class LatencyStrategyImpl_2:public LatencyStrategy{
public:
~LatencyStrategyImpl_2(){}

float getLatency(){
//get load here
float latency = 0.0;
return latency;
}
};

#endif

//Display.h

#ifndef Display_h
#define Display_h

#include <iostream>
using namespace std;

class Display{
public:
virtual ~Display(){}
virtual void show(float load, long totalMemory, long usedMemory, float latency) = 0;
};

class DisplayImpl_1:public Display{//Console Display控制台显示
public:
~DisplayImpl_1(){}

void show(float load, long totalMemory, long usedMemory, float latency);
};

class DisplayImpl_2:public Display{
public:
~DisplayImpl_2(){}

void show(float load, long totalMemory, long usedMemory, float latency){
//get load here
}
};

#endif

//Display.cpp

#include <iostream>
#include <iomanip>
#include <windows.h>
#include "Display.h"
using namespace std;

void DisplayImpl_1::show(float load, long totalMemory, long usedMemory, float latency){
cout << "================================================" << endl;

cout << setiosflags(ios::left) << setw(15) << "CPU负载率为:" << resetiosflags(ios::left);
cout << setiosflags(ios::right) << setw(7) << setiosflags(ios::fixed) << setprecision(2)
<< load << "%" << resetiosflags(ios::right) << endl;
//两个setw()都不能少,否则只有一种对齐方式起作用
cout << setiosflags(ios::left) << setw(15) << "总内存为:" << resetiosflags(ios::left);
cout << setiosflags(ios::right) << setw(7) << setiosflags(ios::fixed) << setprecision(2)
<< totalMemory << "MB" << resetiosflags(ios::right) << endl;

cout << setiosflags(ios::left) << setw(15) << "已用内存为:" << resetiosflags(ios::left);
cout << setiosflags(ios::right) << setw(7) << setiosflags(ios::fixed) << setprecision(2)
<< usedMemory << "MB" << resetiosflags(ios::right) << endl;

cout << endl << endl;
}


依然有两条提示左移操作越界的警告:



以及由于多个时延叠加而导致控制台的时延明显拖长:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐