【问题标题】:How to get current CPU and RAM usage in C++?如何在 C++ 中获取当前的 CPU 和 RAM 使用情况?
【发布时间】:2010-10-03 13:03:10
【问题描述】:

是否有可能在 C++ 中获得当前的 RAM 和 CPU 使用率?是否有独立于平台的函数调用?

【问题讨论】:

    标签: c++ cpu-usage ram


    【解决方案1】:

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

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

    【讨论】:

    • 为什么会如此悲伤? CPU/RAM/NUMA/(在此处插入一个或多个首字母缩写词)种类繁多,使得独立于平台的报告机制有些受限。
    • getrusage 大部分字段都没有设置,目前RAM使用没有根据你的链接设置
    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

      据我所知,没有一个独立于平台的函数。如果您计划针对多个版本的 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】:

        不,没有,不在标准中。

        如果您确实需要此信息,则必须编写特定于平台的#ifdefs 或链接到提供它的库。

        【讨论】:

          【解决方案5】:

          在 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】:

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

            Here's more on how to use it.

            【讨论】:

              【解决方案7】:

              不直接。

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

              【讨论】:

                【解决方案8】:

                如果还是这样,请检查:

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

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

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

                【讨论】:

                  【解决方案9】:

                  我注意到ACE 被移植到vcpkg,这将使编译和链接跨平台 C++ 应用程序变得容易。

                  在 C++ 中,我想监控可用的系统 CPU 和内存资源,以便我的应用可以根据资源可用性调整其消耗。

                  有没有人可以提供一个 ACE 代码 sn-p 来开始这项工作?

                  【讨论】:

                    猜你喜欢
                    • 2010-09-21
                    • 2010-11-18
                    • 1970-01-01
                    • 1970-01-01
                    • 2011-04-27
                    • 1970-01-01
                    • 1970-01-01
                    相关资源
                    最近更新 更多