Как определить объем оперативной памяти Linux в C++?

Я просто написал следующую функцию C++, чтобы программно определить, сколько оперативной памяти установлено в системе. Это работает, но мне кажется, что должен быть более простой способ сделать это. Может кто-нибудь сказать мне, если я что-то упускаю?

getRAM()
{
    FILE* stream = popen( "head -n1 /proc/meminfo", "r" );
    std::ostringstream output;
    int bufsize = 128;

    while( !feof( stream ) && !ferror( stream ))
    {
        char buf[bufsize];
        int bytesRead = fread( buf, 1, bufsize, stream );
        output.write( buf, bytesRead );
    }
    std::string result = output.str();

    std::string label, ram;
    std::istringstream iss(result);
    iss >> label;
    iss >> ram;

    return ram;
}

Во-первых, я использую popen("head -n1 /proc/meminfo"), чтобы получить первую строку файла meminfo из системы. Результат этой команды выглядит как

MemTotal: 775280 kB

Как только я получу этот вывод в istringstream, его просто токенизировать, чтобы получить нужную мне информацию. Мой вопрос: есть ли более простой способ прочитать вывод этой команды? Есть ли вызов стандартной библиотеки C++ для чтения в объеме системной ОЗУ?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
31
0
35 436
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Даже top (из procps) анализирует /proc/meminfo, см. здесь.

Нет необходимости использовать popen(), вы можете просто прочитать файл самостоятельно. Кроме того, если первая строка не та, которую вы ищете, вы потерпите неудачу, поскольку head -n1 считывает только первую строку, а затем завершает работу. Я не уверен, почему вы так смешиваете ввод-вывод C и C++; это нормально, но вам, вероятно, следует выбрать полностью C или полностью C++. Я бы, наверное, сделал это примерно так:

int GetRamInKB(void)
{
    FILE *meminfo = fopen("/proc/meminfo", "r");
    if (meminfo == NULL)
        ... // handle error

    char line[256];
    while(fgets(line, sizeof(line), meminfo))
    {
        int ram;
        if (sscanf(line, "MemTotal: %d kB", &ram) == 1)
        {
            fclose(meminfo);
            return ram;
        }
    }

    // If we got here, then we couldn't find the proper line in the meminfo file:
    // do something appropriate like return an error code, throw an exception, etc.
    fclose(meminfo);
    return -1;
}

В первой строке было / proc / meminfo была информация, которую я искал. Я возвращаюсь к C++ через много лет, поэтому я еще не очень хорошо разбираюсь в стилях C и C++, но я над этим работаю. Спасибо. :)

Bill the Lizard 08.12.2008 19:27
Ответ принят как подходящий

В Linux вы можете использовать функцию sysinfo, которая устанавливает значения в следующей структуре:

   #include <sys/sysinfo.h>

   int sysinfo(struct sysinfo *info);

   struct sysinfo {
       long uptime;             /* Seconds since boot */
       unsigned long loads[3];  /* 1, 5, and 15 minute load averages */
       unsigned long totalram;  /* Total usable main memory size */
       unsigned long freeram;   /* Available memory size */
       unsigned long sharedram; /* Amount of shared memory */
       unsigned long bufferram; /* Memory used by buffers */
       unsigned long totalswap; /* Total swap space size */
       unsigned long freeswap;  /* swap space still available */
       unsigned short procs;    /* Number of current processes */
       unsigned long totalhigh; /* Total high memory size */
       unsigned long freehigh;  /* Available high memory size */
       unsigned int mem_unit;   /* Memory unit size in bytes */
       char _f[20-2*sizeof(long)-sizeof(int)]; /* Padding for libc5 */
   };

Если вы хотите сделать это исключительно с использованием функций C++ (я бы придерживался sysinfo), я рекомендую использовать подход C++ с использованием std::ifstream и std::string:

unsigned long get_mem_total() {
    std::string token;
    std::ifstream file("/proc/meminfo");
    while(file >> token) {
        if (token == "MemTotal:") {
            unsigned long mem;
            if (file >> mem) {
                return mem;
            } else {
                return 0;       
            }
        }
        // ignore rest of the line
        file.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
    }
    return 0; // nothing found
}

Стоит отметить, что freeram в sysinfo - это не то, что большинство людей называют «свободной оперативной памятью». freeramисключает память, используемая кэшированными метаданными файловой системы («буферы») и содержимым («кеш»). Оба они могут составлять значительную часть ОЗУ, но освобождаются ОС, когда программам требуется эта память. sysinfo содержит размер, используемый буферами (sysinfo.bufferram), но не кеш. Лучшим вариантом является использование записи MemAvailable (в отличие от MemFree) в /proc/meminfo.

Vicky Chijwani 29.07.2016 14:01

Этот Сообщение о фиксации ядра Linux объясняет, что есть еще нюансы. В нем говорится: «Многие программы проверяют / proc / meminfo, чтобы оценить, сколько свободной памяти доступно. Обычно они делают это, складывая« свободную »и« кэшированную », что было хорошо десять лет назад, но это почти гарантированно ошибаюсь сегодня».

Vicky Chijwani 29.07.2016 14:08

Объем памяти, показанный в /proc/meminfo, может не соответствовать объему установленной RAM физически. например. если на машине установлено 16 ГБ модулей ОЗУ и она загружается нормально, meminfo показывает 16 ГБ. Однако, если машина загружается с параметром ядра mem=4GB, meminfo показывает 4 ГБ, в то время как фактическая ОЗУ действительно составляет 16 ГБ. Иногда это имеет значение (читайте комментарии в unix.stackexchange.com/questions/500089/…)

Danny 29.03.2019 13:15

Помните, что / proc / meminfo - это просто файл. Откройте файл, прочтите первую строку, закройте файл. Вуаля!

Другие вопросы по теме