あなたは正しいアプローチをしています。
STDOUTに書き込む場合STDOUTは、端末(「ラインバッファリング」)であるとき、改行が検出されたとき、ほとんどのプログラムは、それらの出力をフラッシュ
my @cmd = ('perl', '-e', '$|=1; for (1..5) { print "$_\n"; sleep 1; }');
open(my $pipe, '-|', @cmd)
or die("Can't launch child: $!\n");
while (defined(my $line = <$pipe>)) {
chomp($line);
print "<$line>\n";
}
。ほとんどのプログラムは、STDOUTが端末でない場合(「ブロックバッファリング」)、4KiBまたは8KiBの出力チャンクをブロックします。そのため、上記の例の子プログラムで$|=1;
を使用しなければならなかったのです。
説明どおりに動作するプログラムは、パイプの代わりに擬似端末を使用するラインバッファリングを使用することになります。
my @cmd = ('unbuffer', 'perl', '-e', 'for (1..5) { print "$_\n"; sleep 1; }');
open(my $pipe, '-|', @cmd)
or die("Can't launch child: $!\n");
while (defined(my $line = <$pipe>)) {
chomp($line);
print "<$line>\n";
}
IPC::Runは、擬似端末を作成するネイティブな方法を提供します。
use IPC::Run qw(run);
my @cmd = ('perl', '-e', 'for (1..5) { print "$_\n"; sleep 1; }');
my $buf = '';
run(\@cmd, '>pty>', sub {
$buf .= $_[0];
while ($buf =~ s/^(.*)\r\n//) {
print "<$1>\n";
}
});
私はソケットがバックチックと関係しているのか分かりません。あなたは、プログラムのSTDOUTやソケットを読みたいと思っていますか? – ikegami
私はstdoutを非同期に読み込み、改行がstdoutに追加されるとすぐに出力したいと考えています。ソケットの部分は重要ではありません。 – TheAschr
1つ以上の入力**から**非同期的に読み取るには、0以上のクライアントにイベントを送信するには、*非ブロッキングIO *を使用し、すべてのIOを同時にアドレス指定するために 'select'コマンドを使用する必要があります... –