возможно ли в C ++ получить текущее использование ОЗУ и ЦП? Есть ли вызов функции, не зависящей от платформы?
Как узнать текущее использование ЦП и ОЗУ в C ++?
Ответы (9)
Существует библиотека с открытым исходным кодом, которая предоставляет эти (и другие сведения о системе) на многих платформах: SIGAR API
Я использовал его в довольно крупных проектах, и он отлично работает (за исключением некоторых угловых случаев в OS X и т. Д.)
К сожалению, эти вещи в значительной степени зависят от базовой ОС, поэтому независимых от платформы вызовов нет. (Может быть, есть какие-то фреймворки-оболочки, но я ничего не знаю.)
В Linux вы можете взглянуть на вызов функции getrusage (), в Windows вы можете используйте GetProcessMemoryInfo () для использования ОЗУ. Также ознакомьтесь с другими функциями в Process Status API Windows.
Насколько мне известно, для этого не существует независимой от платформы функции. ЕСЛИ вы планируете использовать несколько версий Windows, имейте в виду, что реализация в некоторых версиях различается. Я столкнулся с этой проблемой, когда тестировал приложение под NT 3.51, например ... (архаично, я знаю).
Вот код, который я использовал для работы с памятью. Это не работает на платформах, отличных от Windows, и просто вернет 0 при компиляции без определения WIN32:
РЕДАКТИРОВАТЬ: я забыл упомянуть, что этот код делится и округляется до ближайшего МБ, поэтому повсюду >> 20.
// get memory info...
int getTotalRAM()
{
int ret = 0;
#ifdef WIN32
DWORD v = GetVersion();
DWORD major = (DWORD)(LOBYTE(LOWORD(v)));
DWORD minor = (DWORD)(HIBYTE(LOWORD(v)));
DWORD build;
if (v < 0x80000000) build = (DWORD)(HIWORD(v));
else build = 0;
// because compiler static links the function...
BOOL (__stdcall*GMSEx)(LPMEMORYSTATUSEX) = 0;
HINSTANCE hIL = LoadLibrary(L"kernel32.dll");
GMSEx = (BOOL(__stdcall*)(LPMEMORYSTATUSEX))GetProcAddress(hIL, "GlobalMemoryStatusEx");
if(GMSEx)
{
MEMORYSTATUSEX m;
m.dwLength = sizeof(m);
if(GMSEx(&m))
{
ret = (int)(m.ullTotalPhys>>20);
}
}
else
{
MEMORYSTATUS m;
m.dwLength = sizeof(m);
GlobalMemoryStatus(&m);
ret = (int)(m.dwTotalPhys>>20);
}
#endif
return ret;
}
int getAvailRAM()
{
int ret = 0;
#ifdef WIN32
DWORD v = GetVersion();
DWORD major = (DWORD)(LOBYTE(LOWORD(v)));
DWORD minor = (DWORD)(HIBYTE(LOWORD(v)));
DWORD build;
if (v < 0x80000000) build = (DWORD)(HIWORD(v));
else build = 0;
// because compiler static links the function...
BOOL (__stdcall*GMSEx)(LPMEMORYSTATUSEX) = 0;
HINSTANCE hIL = LoadLibrary(L"kernel32.dll");
GMSEx = (BOOL(__stdcall*)(LPMEMORYSTATUSEX))GetProcAddress(hIL, "GlobalMemoryStatusEx");
if(GMSEx)
{
MEMORYSTATUSEX m;
m.dwLength = sizeof(m);
if(GMSEx(&m))
{
ret = (int)(m.ullAvailPhys>>20);
}
}
else
{
MEMORYSTATUS m;
m.dwLength = sizeof(m);
GlobalMemoryStatus(&m);
ret = (int)(m.dwAvailPhys>>20);
}
#endif
return ret;
}
int getTotalMemory()
{
int ret = 0;
#ifdef WIN32
DWORD v = GetVersion();
DWORD major = (DWORD)(LOBYTE(LOWORD(v)));
DWORD minor = (DWORD)(HIBYTE(LOWORD(v)));
DWORD build;
if (v < 0x80000000) build = (DWORD)(HIWORD(v));
else build = 0;
// because compiler static links the function...
BOOL (__stdcall*GMSEx)(LPMEMORYSTATUSEX) = 0;
HINSTANCE hIL = LoadLibrary(L"kernel32.dll");
GMSEx = (BOOL(__stdcall*)(LPMEMORYSTATUSEX))GetProcAddress(hIL, "GlobalMemoryStatusEx");
if(GMSEx)
{
MEMORYSTATUSEX m;
m.dwLength = sizeof(m);
if(GMSEx(&m))
{
ret = (int)(m.ullTotalPhys>>20) + (int)(m.ullTotalVirtual>>20);
}
}
else
{
MEMORYSTATUS m;
m.dwLength = sizeof(m);
GlobalMemoryStatus(&m);
ret = (int)(m.dwTotalPhys>>20) + (int)(m.dwTotalVirtual>>20);
}
#endif
return ret;
}
int getAvailMemory()
{
int ret = 0;
#ifdef WIN32
DWORD v = GetVersion();
DWORD major = (DWORD)(LOBYTE(LOWORD(v)));
DWORD minor = (DWORD)(HIBYTE(LOWORD(v)));
DWORD build;
if (v < 0x80000000) build = (DWORD)(HIWORD(v));
else build = 0;
// because compiler static links the function...
BOOL (__stdcall*GMSEx)(LPMEMORYSTATUSEX) = 0;
HINSTANCE hIL = LoadLibrary(L"kernel32.dll");
GMSEx = (BOOL(__stdcall*)(LPMEMORYSTATUSEX))GetProcAddress(hIL, "GlobalMemoryStatusEx");
if(GMSEx)
{
MEMORYSTATUSEX m;
m.dwLength = sizeof(m);
if(GMSEx(&m))
{
ret = (int)(m.ullAvailPhys>>20) + (int)(m.ullAvailVirtual>>20);
}
}
else
{
MEMORYSTATUS m;
m.dwLength = sizeof(m);
GlobalMemoryStatus(&m);
ret = (int)(m.dwAvailPhys>>20) + (int)(m.dwAvailVirtual>>20);
}
#endif
return ret;
}
Нет, не в стандарте.
Если вам действительно нужна эта информация, вам придется написать #ifdef для конкретной платформы или связать ее с библиотекой, которая ее предоставляет.
В Linux это будет использовать / proc / self / status. Требуется дополнительная работа, чтобы превратить это в число. Я считаю, что это полезно, просто для вывода использования памяти прямо на экран в виде строки.
static string memory_usage() {
ostringstream mem;
PP("hi");
ifstream proc("/proc/self/status");
string s;
while(getline(proc, s), !proc.fail()) {
if(s.substr(0, 6) == "VmSize") {
mem << s;
return mem.str();
}
}
return mem.str();
}
Не существует независимого от платформы способа сделать это. Хотя для Windows вы можете получить показатели использования ЦП и производительности, используя PDH.dll (Performance Data Helper) и связанные с ним API в вашем коде.
Подробнее о том, как его использовать.
Не прямо.
Но вы можете использовать библиотеку, которая абстрагирует ОС (например, ACE).
Хотя это может быть немного сложно, если вам просто нужен процессор и память.
Если это все еще так, проверьте:
http://sourceforge.net/projects/cpp-cpu-monitor/
Он дает вам пример того, как узнать использование ЦП и ОЗУ Linux (протестировано на Debian и CentOS), и довольно простую инструкцию по установке.
Не стесняйтесь спрашивать, есть ли у вас какие-либо вопросы относительно этого небольшого проекта.
Я заметил, что ACE перенесен на vcpkg, который упростит компиляцию и компоновку кроссплатформенного приложения C ++.
В C ++ я хотел бы отслеживать доступные ресурсы ЦП и памяти системы, чтобы мое приложение могло изменять потребление в зависимости от доступности ресурсов.
Кто-нибудь может предложить фрагмент кода ACE, чтобы начать работу над этим?