У меня есть скрипт Perl, который использует внешний инструмент (cleartool) для сбора информации о списке файлов. Я хочу использовать IPC, чтобы избежать порождения нового процесса для каждого файла:Как сделать неблокирующее IPC, прочитанное в Windows?
use IPC::Open2;
my ($cin, $cout);
my $child = open2($cout, $cin, 'cleartool');
Команды, которые возвращают одиночные линии работают хорошо. например
print $cin "describe -short $file\n";
my $description = <$cout>;
Команды, которые возвращают несколько строк у меня в тупик для того, как потреблять весь ответ без получения подвешивали блокированию чтения:
print $cin "lshistory $file\n";
# read and process $cout...
Я попытался установить указатель файла для неблокирующая читает через fcntl
:
use Fcntl;
my $flags = '';
fcntl($cout, F_GETFL, $flags);
$flags |= O_NONBLOCK;
fcntl($cout, F_SETFL, $flags);
но Fcntl умирает с сообщением «Ваш поставщик не определен Fcntl макрос F_GETFL.»
Я пробовал использовать IO :: Ручка для установки $cout->blocking(0)
, но это не удалось (оно возвращает undef
и устанавливает $!
в «Неизвестная ошибка»).
Я пытался использовать select
, чтобы определить, есть ли имеющиеся данные, прежде чем читать:
my $rfd = '';
vec($rfd, fileno($cout), 1) = 1;
while (select($rfd, undef, undef, 0) >= 0) {
my $n = read($cout, $buffer, 1024);
print "Read $n bytes\n";
# do something with $buffer...
}
но висит никогда не читал ничего. Кто-нибудь знает, как сделать эту работу (в Windows)?
Что вы планируете делать, не блокируя IO? – jrockway
Я хочу читать до тех пор, пока не перестану получать данные, которые, казалось бы, были бы более надежными, чем попытка определить, что я дошел до конца, проанализировав данные, которые я уже получил. (В данных нет индикатора «это последняя строка».) –
Поиск вокруг связанной проблемы, я нашел это фиксацию на GitHub, который, кажется, вызывает черную магию для создания неблокирующего сокета: https: // github .com/kthakore/frozen-bubble/commit/735dd2307455e32c69827e013992c2d022cb7347 –