gpt4 book ai didi

无缓冲或行缓冲的 Perl STDIN

转载 作者:行者123 更新时间:2023-12-01 11:39:08 25 4
gpt4 key购买 nike

我有一个 Perl 脚本,它接收从另一个程序通过管道传输的输入。它使用 8k(Ubuntu 默认)输入缓冲区进行缓冲,这会导致问题。我想使用行缓冲或完全禁用缓冲。看起来没有什么好方法可以做到这一点。有什么建议?

use IO::Handle;
use IO::Poll qw[ POLLIN POLLHUP POLLERR ];
use Text::CSV;

my $stdin = new IO::Handle;
$stdin->fdopen(fileno(STDIN), 'r');
$stdin->setbuf(undef);

my $poll = IO::Poll->new() or die "cannot create IO::Poll object";
$poll->mask($stdin => POLLIN);

STDIN->blocking(0);

my $halt = 0;
for(;;) {
$poll->poll($config{poll_timout});

for my $handle ($poll->handles(POLLIN | POLLHUP | POLLERR)) {
next unless($handle eq $stdin);

if(eof) {
$halt = 1;
last;
}

my @row = $csv->getline($stdin);
# Do more stuff here
}

last if($halt);
}

由于 IO::Poll 使用缓冲,而像 sysread 这样的直接调用不使用(并且它们不能混合),因此轮询 STDIN 有点麻烦。我不想在没有阻塞的情况下无限调用 sysread。我需要使用 selectpoll因为我不想锤CPU。

请注意:我说的是标准输入,而不是标准输出。 $|++ 不是解决方案。

[编辑]
根据评论和其他答案更新我的问题以澄清。

写入 STDOUT(在管道的另一侧)的程序在每次写入后都会被行缓冲和刷新。每次写入都包含一个换行符,因此实际上,对于第一个程序的 STDOUT 而言,缓冲不是问题。

为了验证这是真的,我写了一个小的 C 程序,它从同一个程序中读取管道输入,并禁用 STDIN 缓冲(setvbuf 和 _IONBF)。输入立即出现在测试程序的 STDIN 中。遗憾的是,第一个程序的输出似乎不是问题。
[/编辑]

感谢您的任何见解!

附注。我已经做了大量的谷歌搜索。 This link是我找到的最接近答案的方法,但它肯定不能满足我的所有需求。

最佳答案

您实际上是在谈论其他程序的 STDOUT。解决方法是$|=1; (或等效的)在另一个程序中。

如果不能,您可以说服其他程序使用行缓冲而不是块缓冲,方法是将其 STDOUT 连接到伪 tty 而不是管道(例如,像 Expect.pm 那样)。

unix程序expect有一个工具叫 unbuffer正是这样做的。 (它是 Ubuntu 上 expect-dev 包的一部分。)只需在命令名称前加上 unbuffer .

关于无缓冲或行缓冲的 Perl STDIN,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23502239/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com