Я просто написал следующую функцию 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++ для чтения в объеме системной ОЗУ?





Даже 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;
}
В 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.
Этот Сообщение о фиксации ядра Linux объясняет, что есть еще нюансы. В нем говорится: «Многие программы проверяют / proc / meminfo, чтобы оценить, сколько свободной памяти доступно. Обычно они делают это, складывая« свободную »и« кэшированную », что было хорошо десять лет назад, но это почти гарантированно ошибаюсь сегодня».
Объем памяти, показанный в /proc/meminfo, может не соответствовать объему установленной RAM физически. например. если на машине установлено 16 ГБ модулей ОЗУ и она загружается нормально, meminfo показывает 16 ГБ. Однако, если машина загружается с параметром ядра mem=4GB, meminfo показывает 4 ГБ, в то время как фактическая ОЗУ действительно составляет 16 ГБ. Иногда это имеет значение (читайте комментарии в unix.stackexchange.com/questions/500089/…)
Помните, что / proc / meminfo - это просто файл. Откройте файл, прочтите первую строку, закройте файл. Вуаля!
В первой строке было / proc / meminfo была информация, которую я искал. Я возвращаюсь к C++ через много лет, поэтому я еще не очень хорошо разбираюсь в стилях C и C++, но я над этим работаю. Спасибо. :)