【问题标题】:When using system() in c++ my program gets stuck, how do I get it to proceed?在 c++ 中使用 system() 时,我的程序卡住了,我该如何让它继续?
【发布时间】:2014-04-27 23:42:58
【问题描述】:

我正在制作一个磁盘实用工具,它获取磁盘统计信息(在 linux 中)并从中计算值。我的基本问题是,当 system() 调用发生时,程序挂在那里。

   system("grep 'sda ' /proc/diskstats | tee \"report.txt\"");
   ifstream inStream;
   inStream.open("report.txt");
if (inStream.fail()) {
    cout << "Report gathering failed." << endl;
    return;
}
while (!inStream.eof()) {
    inStream.ignore();
    inStream.ignore();
    inStream.ignore();
    inStream >> numReads1;
    inStream.ignore();
    inStream >> sectorReads1;
    inStream.ignore();
    inStream >> numWrites1;
    inStream.ignore();
    inStream >> sectorWrites1;
    inStream.ignore();
    inStream.ignore();
    inStream.ignore();
    inStream.ignore();
}

【问题讨论】:

  • 您的程序上的ptrace 可能会发现有趣的数据。
  • 我会先使用popen 而不是system
  • 您是否能够在 bash shell 中运行该命令,而与您的程序无关?正常结束吗?
  • 有比使用 system 和中间文件更好的 C++ 方法:PStreamsBoost.ProcessPOCO Process - 其中大部分是围绕 popen 的包装器。跨度>
  • 你真的要使用tee吗?尝试使用输出重定向 &gt; 将管道替换为 tee。

标签: c++ linux terminal


【解决方案1】:

system("grep 'sda ' /proc/diskstats | tee \"report.txt\"");

你为什么这样做?当然会挂了。 tee 将所有输入复制到标准输出以及作为tee 的参数指定的每个文件。您没有从tee 的标准输出中读取任何内容。如果有足够的匹配,输出缓冲区将被填满,进程将挂起。

您可以使用system 完成的操作是

system("grep 'sda ' /proc/diskstats > report.txt");

report.txt 不需要引号,tee 也不需要。但是,如果您不需要该文件,则没有理由编写该文件。你可以改用popen

FILE* grep_sda = popen (""grep 'sda ' /proc/diskstats", "r");

注意popen 的结果是一个FILE 指针。您在这里有三个选择:

  • 使用 C 风格的 I/O 读取 FILE 指针。
  • 如果幸运的话,有些系统会为 std::fstream 提供非标准构造函数,这些构造函数可以从 C 流构造 C++ 文件流。
  • 可能有一个提升解决方案。我不能在工作中使用 Boost,请不要在工作之外使用它。

另一种选择是绕过grep。这里不需要grep,因为模式非常简单。以 C++ std::ifstream 的形式打开文件,使用 std::getline 从其中读取行,过滤与 std::find 匹配的行,然后解析匹配的行。

【讨论】:

    猜你喜欢
    • 2021-04-25
    • 1970-01-01
    • 2023-04-09
    • 1970-01-01
    • 2014-07-04
    • 2012-12-04
    • 1970-01-01
    • 1970-01-01
    • 2022-10-21
    相关资源
    最近更新 更多