代码之家  ›  专栏  ›  技术社区  ›  tunnuz

如何在C++中获取当前的CPU和RAM使用情况?

  •  31
  • tunnuz  · 技术社区  · 17 年前

    在C++中,是否有可能获取当前的RAM和CPU使用情况?是否存在与平台无关的函数调用?

    9 回复  |  直到 12 年前
        1
  •  30
  •   Kosi2801    17 年前

    遗憾的是,这些东西在很大程度上依赖于底层操作系统,因此没有独立于平台的调用。(也许有一些包装框架,但我不知道有什么。)

    在Linux上,你可以看看 getrusage() 函数调用,在Windows上可以使用 GetProcessMemoryInfo() RAM使用情况。还可以查看中的其他功能 Process Status API Windows。

        2
  •  11
  •   jheriko    17 年前

    有一个开源库可以在许多平台上提供这些(以及更多的系统信息): SIGAR API

    我在相当大的项目中使用过它,它工作得很好(除了OS X上的某些极端情况等)

        3
  •  11
  •   pptaszni    6 年前

    据我所知,没有独立于平台的功能。如果您计划针对多个版本的Windows,请注意某些版本的实现方式不同。例如,我在测试NT 3.51下的应用程序时遇到了这个问题。..(我知道很古老)。

    这是我用于内存方面的一些代码。这在windows以外的平台上不起作用,在没有WIN32定义的情况下编译时只会返回0:

    编辑:我忘了提到,这段代码进行除法运算,并四舍五入到最接近的MB,因此>>到处都是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;
    }
    
        4
  •  5
  •   HUAGHAGUAH    17 年前

    不,标准中没有。

    如果你真的需要这些信息,你必须编写特定于平台的#ifdef或链接到提供它的库。

        5
  •  2
  •   Aaron McDaid    15 年前

    在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();
    }
    
        6
  •  1
  •   Samrat Patil    17 年前

    没有独立于平台的方法可以做到这一点。虽然对于windows,您可以通过在代码中使用PDH.dll(性能数据助手)及其相关API来获取CPU使用率和性能指标。

    Here's more on how to use it.

        7
  •  0
  •   Loki Astari    17 年前

    不是直接。

    但是,您可以使用抽象操作系统的库(如ACE)。
    如果你只需要CPU和内存,这可能会有点重。

        8
  •  0
  •   Bartosz Pachołek    13 年前

    如果情况仍然如此,请检查:

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

    它为您提供了一个如何获取Linux(在Debian和CentOS上测试)的CPU和RAM使用率的示例,以及一个非常简单的安装说明。

    如果您对这个小项目有任何疑问,请随时提问。

        9
  •  0
  •   GoFaster    6 年前

    我注意到了 ACE 被移植到 vcpkg 这将使其易于编译和使用;链接跨平台C++应用程序。

    在C++中,我想监控可用的系统CPU和内存资源,这样我的应用程序就可以根据资源可用性灵活调整其消耗。

    有人能提供一个ACE代码片段来开始吗?