创建管道但稍后读取其标准输出

问题描述 投票:0回答:2

我创建了用于读取的管道(在 C 中使用

popen
)并使用 fgets 读取其输出 - 并且效果很好。

但现在我需要两项改进,并且不知道如何进行 - 大多数答案都相对较旧,也许问题已经解决但我找不到它。

所以:

  1. 使管道读取异步。我可以使用this建议来做到这一点。现在我应该能够在等待来自管道的数据时执行其他操作,或者使用超时计时器在管道挂起时将其关闭。
  2. 稍后读取管道 - 打开管道,然后执行一些任务,然后在一段时间后返回读取管道 - 让管道应用程序完成其工作并向管道执行输出 - 这样我就可以开始读取管道,其工作已经在进行中,不是刚刚开始。这需要一些缓冲,但似乎没有太多控制权。目前尚不清楚缓冲区大小是多少,以及如果在各种实现上不被读取,管道将如何表现。

最明显的方法是创建一个用于管道的线程,它将与主任务并行地执行输出收集。但有没有更好、更简单的方法呢?谢谢。

c linux pipe stdout
2个回答
0
投票

我看到两个选项。

  1. 创建一个从管道读取数据的线程,并将结果放入您可以控制的缓冲区(必要时动态增长)中。
  2. 使用
    select
    (类似)等待不同文件描述符上的事件。 POSIX 还支持
    poll
    ,Linux 还支持
    epoll

0
投票

这取决于进程中管道的非阻塞读取之间的预期时间间隔,以及由

popen
启动的特定程序。

如果间隔太长以致管道缓冲区已满,则管道写入端的大多数程序的默认行为是阻塞。虽然它们在写入管道时被阻止,但它们可能也不会做任何其他事情,除非它们是多线程的。

您可以尝试在短时间内发送大量输出的子进程,例如在大文件上的

cat

pipe(7)
手册页告诉我们:

管道容量

管道的容量是有限的。如果管道已满,则 write(2) 将阻塞或失败,具体取决于 O_NONBLOCK 是否 标志已设置(见下文)。不同的实现有 管道容量的不同限制。应用程序不应 依赖于特定的能力:应该设计一个应用程序 以便读取过程立即消耗数据 可用,这样写入过程就不会被阻塞。

© www.soinside.com 2019 - 2024. All rights reserved.