Похоже, вы смешиваете буферизованный и небуферизованный ввод / вывод.
<READER>
(и readline(READER)
) - буферизованные операции ввода. При первом вызове readline
для дескриптора файла Perl попытается прочитать до 8K данных из дескриптора, сохранив большую их часть в буфере памяти. В следующий раз, когда вы вызовете readline
для того же дескриптора файла, Perl попытается вернуть данные в буфер, прежде чем попытаться снова прочитать больше данных из файла. Это для эффективности.
select
- это операция для небуферизованного ввода-вывода. Он сообщает вам, ожидает ли ввод самого дескриптора файла, но не может увидеть, ожидают ли данные в буфере.
Неуклюжей альтернативой будет использование sysread
или getc
для извлечения данных из канала. Это неудобно, потому что вам придется разбивать ввод самостоятельно на отдельные строки.
... if ($read_avail > 0) {
my $n = sysread READER, my $lines, 16384;
chomp($lines);
my @lines = split /\n/, $lines;
print "Parent Got $$: '$_'\n" for @lines;
} ...
Что может сработать, так это чтение из дескриптора файла в контексте списка.
chomp(my @lines = <READER>);
seek READER, 0, 1;
должен прочитать все доступные данные из буфера и дескриптора файла, и теоретически он оставит ваш буфер пустым, поэтому следующий вызов <READER>
будет похож на небуферизованное чтение. (Оператор seek
очищает условие EOF для файлового дескриптора, так что вы можете читать из файлового дескриптора позже, когда поступит больше ввода).
(ETA: нет, это не сработает. Это просто заблокирует READER
, пока ребенок не закроет свой конец канала)
Документы для select
имеют это предупреждение
ПРЕДУПРЕЖДЕНИЕ: Не следует пытаться смешивать буферизованный ввод / вывод (например,
«read
» или <FH>
) с «select
», за исключением случаев, разрешенных POSIX,
и даже тогда только в системах POSIX. Вы должны использовать "sysread
"
вместо этого.