使用C ++解析/ proc / stat

时间:2019-02-21 14:09:47

标签: c++ ubuntu-16.04

我是c ++的新手,在Linux中有点新手。我有一个简单的项目,需要从/ proc / stat文件解析CPU统计信息并计算CPU使用率。我尝试在完整的bash脚本上执行此操作。但是我需要的是c ++。我只需要一点帮助。 / proc / stat给出了很多数字,我知道不同的列代表的东西。例如User,Nice,System,Idle等。例如,我只想获取Idle值,并使用c ++将其存储为Integer,我该怎么做?请帮忙。我现在尝试的只是使用ifstream和getline()来获得我需要的整行

std::ifstream filestat("/proc/stat");
std::string line;
std::getline(filestat,line);

这就是我的意思。

cpu  349585 0 30513 875546 0 935 0 0 0 0

例如,为了澄清我的问题,我想获取875546值,并使用c ++将其存储为整数。我该怎么办?谢谢

3 个答案:

答案 0 :(得分:1)

stat 的格式在 proc(5) 手册页中有详细描述。 您可以通过从 Linux 终端运行命令 man 5 proconline 来查看它。

上述解析 stat 文件的方法适用于学术目的,但生产级解析器在使用这些方法时应格外小心。

如果您需要 C++ 中的生产级解析器来处理 /proc 中的文件,您可以查看 pfs - 用于解析 procfs 的库(免责声明:我是图书馆的作者)

最大的问题通常是 comm 字段(文件中的第二个字段)。 根据手册页,该字段是一个应该使用某种 scanf 风格和格式化程序 %s 进行“扫描”的字符串。 但那是错误的!

comm 字段由应用程序控制(可以使用 prctl(PR_SET_NAME, ...) 设置)并且可以很容易地包含空格或括号,很容易导致 99% 的解析器失败。 像这样的简单更改不仅会返回错误的 comm 值,还会导致其后的所有值搞砸。

解析文件的正确方式是以下之一:

  1. 选项 1:

    1. 阅读文件的全部内容
    2. 找到第一次出现的 '('
    3. 找到最后一次出现的 ')'
    4. 分配给这些索引之间的字符串
    5. 在最后一次出现“)”后解析文件的其余部分
  2. 选项 2:

    1. 读取 PID(文件中的第一个值)
    2. 读取 18 个字节(16 是最大的通信值 + 2 用于包装括号)
    3. 从该缓冲区中提取通信值,就像我们对选项 #1 所做的一样
    4. 找出值的实际长度,修复您的流并从那里继续阅读

答案 1 :(得分:0)

您确实需要研究文件输入的工作方式。这应该足够简单。您只需忽略3个字符“ cpu”,然后通读4个整数值:

unsigned n;
if(std::ifstream("/proc/stat").ignore(3) >> n >> n >> n >> n)
{
    // use n here...
    std::cout << n << '\n';
}

或者,如果您已经有了该行(也许一次要读取一行文件),则可以使用std::istringstream将行转换为新的输入流:

std::ifstream filestat("/proc/stat");

std::string line;
std::getline(filestat, line);

unsigned n;
if(std::istringstream(line).ignore(3) >> n >> n >> n >> n)
{
    // use n here...
    std::cout << n << '\n';
}

答案 2 :(得分:0)

有几种方法可以解决此问题。您可以使用正则表达式库来获取字符串的一部分,或者如果您知道这始终是第5个元素,则可以使用以下代码:

<label><strong>Get the latest jobs in your inbox!</strong></label>
<input style="width:auto !important" type="email" name="EMAIL" placeholder="your@email.com" required />
<input display="inline-block" position="relative" margin-left="5px" vertical-align="top" type="submit" value="Subscribe" />

希望对您有帮助。