我的程序在Linux上控制外部应用程序,通过管道将输入命令传递到外部应用程序stdin,并通过外部应用程序标准输出管道读取输出结果。
问题是对管道的写入是按块而不是按行缓冲的,因此在我的应用程序接收外部应用程序输出数据之前会发生延迟。无法更改外部应用程序以添加显式fflush()调用。
当我将外部应用程序设置为 / bin / cat -n (它回显输入,添加了行号)时,它可以正常工作,似乎 cat 每行后冲洗。强制外部应用程序刷新的唯一方法是向其发送 exit 命令;当它收到命令时,它会刷新,所有答案都会在退出之前显示在标准输出上。
我很确定,Unix管道对于那种进程间通信(伪服务器 - 客户端)来说是合适的解决方案,但也许我错了。
(我刚刚复制了一些类似问题的文字:Force another program's standard output to be unbuffered using Python)
答案 0 :(得分:5)
不要使用烟斗。请改用pty。 Pty(伪ttys)具有线缓冲的好处,如果你需要它,它可以为你的数据流提供简单的框架。
答案 1 :(得分:2)
使用PTY可能对手头的问题有些过分(尽管将工作)。
如果“目标应用程序”(Delphi命令行实用程序)是动态链接的,则可能更简单的解决方案是将(通过LD_PRELOAD
)小型库插入应用程序。该库只需要实现isatty
,并回答true
(返回1),无论输出是输入管道还是终端。您可能希望对所有文件描述符执行此操作,或仅针对STDOUT_FILENO
。
大多数UNIX实现都会调用isatty
来决定是否对给定的文件描述符执行完全缓冲或行缓冲。
__fxstat
将转到字符设备,则会调用isatty
,然后仅调用fd
。因此,您需要设置__fxstat
和isatty
。有关库插入here的更多信息。
答案 2 :(得分:1)
默认情况下,标准输入和标准输出是完全缓冲的,除非它们连接到交互式设备,在这种情况下它们是行缓冲的[1]。管道是非交互设备。 PTY 是交互式设备。 “完全缓冲”意味着“使用一定大小的内存”。
我确定你想要线缓冲。因此,使用主/从PTY而不是管道应该使受控应用程序自动进入正确的缓冲模式。
[1]详见“stdin(3)”和“setbuf(3)”。
答案 3 :(得分:0)