Как узнать текущее использование ЦП и ОЗУ в C ++?

возможно ли в C ++ получить текущее использование ОЗУ и ЦП? Есть ли вызов функции, не зависящей от платформы?


person tunnuz    schedule 26.01.2009    source источник


Ответы (9)


Существует библиотека с открытым исходным кодом, которая предоставляет эти (и другие сведения о системе) на многих платформах: SIGAR API

Я использовал его в довольно крупных проектах, и он отлично работает (за исключением некоторых угловых случаев в OS X и т. Д.)

person ididak    schedule 28.01.2009

К сожалению, эти вещи в значительной степени зависят от базовой ОС, поэтому независимых от платформы вызовов нет. (Может быть, есть какие-то фреймворки-оболочки, но я ничего не знаю.)

В Linux вы можете взглянуть на вызов функции getrusage (), в Windows вы можете используйте GetProcessMemoryInfo () для использования ОЗУ. Также ознакомьтесь с другими функциями в Process Status API Windows.

person Kosi2801    schedule 26.01.2009
comment
Почему это грустно? Огромное разнообразие CPU / RAM / NUMA / (вставьте здесь один или несколько сокращений) делает механизм отчетности, независимый от платформы, несколько ограниченным. - person MSN; 28.01.2009
comment
getrusage не устанавливает большинство полей, так как на данный момент использование RAM не установлено по вашей ссылке - person Ludovic Zenohate Lagouardette; 08.08.2017

Насколько мне известно, для этого не существует независимой от платформы функции. ЕСЛИ вы планируете использовать несколько версий 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;
}
person jheriko    schedule 26.01.2009

Нет, не в стандарте.

Если вам действительно нужна эта информация, вам придется написать #ifdef для конкретной платформы или связать ее с библиотекой, которая ее предоставляет.

person HUAGHAGUAH    schedule 26.01.2009

В 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();
}
person Aaron McDaid    schedule 05.06.2011

Не существует независимого от платформы способа сделать это. Хотя для Windows вы можете получить показатели использования ЦП и производительности, используя PDH.dll (Performance Data Helper) и связанные с ним API в вашем коде.

Подробнее о том, как его использовать.

person Samrat Patil    schedule 27.01.2009

Не прямо.

Но вы можете использовать библиотеку, которая абстрагирует ОС (например, ACE).
Хотя это может быть немного сложно, если вам просто нужен процессор и память.

person Martin York    schedule 26.01.2009

Если это все еще так, проверьте:

http://sourceforge.net/projects/cpp-cpu-monitor/

Он дает вам пример того, как узнать использование ЦП и ОЗУ Linux (протестировано на Debian и CentOS), и довольно простую инструкцию по установке.

Не стесняйтесь спрашивать, есть ли у вас какие-либо вопросы относительно этого небольшого проекта.

person Bartosz Pachołek    schedule 05.02.2013

Я заметил, что ACE перенесен на vcpkg, который упростит компиляцию и компоновку кроссплатформенного приложения C ++.

В C ++ я хотел бы отслеживать доступные ресурсы ЦП и памяти системы, чтобы мое приложение могло изменять потребление в зависимости от доступности ресурсов.

Кто-нибудь может предложить фрагмент кода ACE, чтобы начать работу над этим?

person GoFaster    schedule 05.03.2020