29

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

4

9 回答 9

30

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

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

于 2009-01-26T13:17:40.697 回答
11

据我所知,没有一个独立于平台的功能。如果您计划针对多个版本的 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;
}
于 2009-01-26T13:50:57.387 回答
11

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

我在相当大的项目中使用过它并且效果很好(除了 OS X 上的某些极端情况等)

于 2009-01-28T08:40:02.240 回答
5

不,没有,不在标准中。

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

于 2009-01-26T13:13:17.040 回答
2

在 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();
}
于 2011-06-05T04:59:10.547 回答
1

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

这里有更多关于如何使用它的信息。

于 2009-01-27T08:55:27.917 回答
0

不是直接的。

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

于 2009-01-26T16:41:11.690 回答
0

如果还是这样,请检查:

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

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

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

于 2013-02-05T10:52:06.347 回答
0

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

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

有没有人可以提供一个 ACE 代码片段来开始这个?

于 2020-03-05T12:01:38.173 回答