【问题标题】:Buffering while popen working工作时缓冲
【发布时间】:2016-07-04 10:10:01
【问题描述】:

我正在使用以下命令来获得两位数值的恒定输出:

pipe = popen("hcidump -a | egrep --line-buffered 'RSSI|bdaddr' | grep -A1 --line-buffered --no-group-separator 'bdaddr 78:A5:04:17:9F:66' | grep -Po --line-buffered 'RSSI:\\s+\\K.*'", "r");

我想缓冲它,所以我可以将它转换为一个整数值并使用它。但我不确定如何实现这一目标。只要我已经打开运行我的 C 程序就不会继续。我用strace查了一下,他会读取popen中的值,不会termit。

其余代码如下所示:

if (pipe) 
    {
        printf("entered pipe-if");

        while(!feof(pipe)) 
        {
            if(fgets(buffer, 128, pipe) != NULL){}
        }   
        pclose(pipe);
        printf("pclose");
        buffer[strlen(buffer)-1] = '\0';
    } 

它背后的想法是我想使用数据“实时”计算距离。一种可能性是我可以告诉 popen 在 x 秒后结束进程,然后使用缓冲的数据,然后从头开始进程。

感谢您的帮助和建议。

【问题讨论】:

  • 你认为为什么会有 EOF?
  • 我知道没有 EOF,我正在尝试一些东西,但仍然存在。把它放在这里是我的错误。

标签: c popen


【解决方案1】:

使用 popen 打开管道后,您应该使用文件描述符而不是 FILE 指针。然后,您可以将文件转换为非阻塞并在数据进入时对其进行处理。

int fd = fileno(pipe);
fcntl(fd, F_SETFL, O_NONBLOCK);

然后你可以使用从管道中读取数据

bytes = read(fd, buf, bufsize);

如果字节数大于 0,那么您需要处理更多数据。如果 bytes 为 -1 且 errno 为 EAGAIN,则管道中没有任何内容。其他任何事情你都完成了。你必须处理数据,不管它进来(即你没有得到 fgets() 很好地每行做事)

【讨论】:

  • 但这不会让我遇到同样的问题吗?当我第一次使用具有永无止境的输出的 popen 时,我永远不会想到 fileno、fcntl 和 read?
  • 通过使文件描述符非阻塞,即使没有输出,您也可以控制程序,因此您可以在必要时实现自己的超时。虽然我不能说我完全理解用例,但在我看来,当您看到新数据时(即每次返回 fgets() 或 read() 在我的版本),而不是在您关闭管道之后。
  • 用例是我想从 iBeacon 读取 RSSI 值,以了解它离我的设备是近、中还是远。并且根据我需要给出进一步说明的值。这就是为什么我需要不断地阅读价值观并对它们做出反应。它不需要是实时的,但经常。意味着我可以收集一些数据(比如一两秒)然后进一步处理。我稍后会尝试你的方法。
猜你喜欢
  • 2013-03-04
  • 2020-11-22
  • 2013-05-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-18
  • 2015-09-14
  • 1970-01-01
相关资源
最近更新 更多