Асинхронно запущенные галочки Perl - PullRequest
4 голосов
/ 06 февраля 2012

Прямо сейчас у меня есть Perl-скрипт, который в определенный момент собирает и затем обрабатывает вывод нескольких команд bash, сейчас вот как я это сделал:

if ($condition) {
  @output = `$bashcommand`;
  @output1 = `$bashcommand1`;
  @output2 = `$bashcommand2`;
  @output3 = `$bashcommand3`;
}

Проблема в том, что каждая из этих команд занимает довольно много времени, поэтому я хотел бы знать, смогу ли я выполнить их все одновременно.

Ответы [ 4 ]

4 голосов
/ 06 февраля 2012

В системе Unix вы должны иметь возможность открыть несколько командных каналов, а затем запустить цикл, вызывающий IO::Select, чтобы дождаться готовности любого из них к чтению; продолжайте читать и копить их вывод (с sysread), пока все они не достигнут конца файла.

К сожалению, очевидно, что Win32-эмуляция Unix select не может обрабатывать файловый ввод / вывод, поэтому, чтобы осуществить его в Windows, вам также нужно будет добавить слой сокетного ввода / вывода, для которого работает select см. perlmonks .

3 голосов
/ 07 февраля 2012

Это звучит как хороший вариант использования для Forks::Super::bg_qx.

use Forks::Super 'bg_qx';
$output = bg_qx $bashcommand;
$output1 = bg_qx $bashcommand1;
$output2 = bg_qx $bashcommand2;
$output3 = bg_qx $bashcommand3;

запустит эти четыре команды в фоновом режиме. Переменные, используемые для возвращаемых значений ($output, $output1 и т. Д.), Являются перегруженными объектами. Ваша программа будет извлекать выходные данные из этих команд (ожидая их завершения при необходимости) при следующем обращении к этим переменным в программе.

... more stuff happens ...
# if $bashcommand is done, this next line will execute right away
# otherwise, it will wait until $bashcommand finishes ...
print "Output of first command was ", $output;

&do_something_with_command_output( $output1 );
@output2 = split /\n/, $output2;
...

Обновление 2012-03-01: v0.60 из Forks :: Super имеет несколько новых конструкций , которые позволяют получать результаты в контексте списка:

if ($condition) {
    tie @output, 'Forks::Super::bg_qx', $bashcommand;
    tie @output1, 'Forks::Super::bg_qx', $bashcommand1;
    tie @output2, 'Forks::Super::bg_qx', $bashcommand2;
    tie @output3, 'Forks::Super::bg_qx', $bashcommand3;
}
...
2 голосов
/ 06 февраля 2012

Вы можете, но без использования обратных галочек.

Вместо этого вам нужно открыть для них настоящие файловые дескрипторы, используя open(handle, "$bashcommand|");, а затем выполнить правильный вызов select, чтобы определить, какой из них имеет новый выход, который готов для вас. Это займет намного больше, чем 6 строк, которые вы указали выше, но вы сможете запускать их все одновременно.

В CPAN есть несколько классов, которые, вероятно, уже справятся с некоторыми сложностями для вас.

0 голосов
/ 06 февраля 2012

Вы должны обратиться к FAQ по Perl .

Proc :: Background выглядит многообещающе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...