2008-12-08 5 views
19

Tôi vừa viết hàm C++ sau để lập trình xác định số lượng RAM mà hệ thống đã cài đặt. Nó hoạt động, nhưng có vẻ như với tôi rằng nên có một cách đơn giản hơn để làm điều này. Ai đó có thể cho tôi biết nếu tôi đang thiếu thứ gì đó?Làm thế nào để bạn xác định số lượng RAM hệ thống Linux trong 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; 
} 

Trước tiên, tôi đang sử dụng popen("head -n1 /proc/meminfo") để nhận dòng đầu tiên của tệp tin từ hệ thống. Kết quả của lệnh đó trông giống như

MemTotal: 775.280 kB

Một khi tôi đã có đầu ra rằng trong một istringstream, thật đơn giản để tokenize nó để có được thông tin mà tôi muốn. Câu hỏi của tôi là, có một cách đơn giản hơn để đọc trong đầu ra của lệnh này? Có một cuộc gọi thư viện C++ chuẩn để đọc số lượng RAM hệ thống không?

Trả lời

62

Trên Linux, bạn có thể sử dụng chức năng sysinfo đó đặt giá trị trong struct sau:

#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 */ 
    }; 

Nếu bạn muốn làm điều đó chỉ sử dụng chức năng C++ (i sẽ dính vào sysinfo), tôi khuyên bạn nên tham gia một cách tiếp cận ++ C sử dụng std::ifstreamstd::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 
} 
+0

sysinfo hoạt động hoàn hảo. Cảm ơn bạn. –

+0

bạn có thể muốn đóng trình xử lý tệp sau khi đọc – segfault

+1

Chắc chắn các trình phá hủy đã làm điều đó rồi. –

0

Thậm chí top (từ procps) phân tích cú pháp /proc/meminfo, xem here.

4

Không cần sử dụng popen(), bạn chỉ có thể tự mình đọc tệp. Ngoài ra, nếu có dòng đầu tiên không phải là những gì bạn đang tìm kiếm, bạn sẽ thất bại, vì head -n1 chỉ đọc dòng đầu tiên và sau đó thoát. Tôi không chắc chắn tại sao bạn đang trộn C và C++ I/O như thế; nó hoàn toàn OK, nhưng bạn có lẽ nên chọn tất cả C hoặc tất cả C++. Tôi có lẽ muốn làm điều đó một cái gì đó như thế này:

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; 
} 
+0

Dòng đầu tiên có/proc/meminfo là thông tin tôi đã theo dõi. Tôi đang trở lại C++ sau nhiều năm, vì vậy tôi chưa có ý thức tốt về phong cách C so với C++, nhưng tôi đang làm việc trên nó. Cảm ơn. :) –

2

Reme mber/proc/meminfo chỉ là một tập tin. Mở tệp, đọc dòng đầu tiên, đóng tệp. Voilá!