Асинхронный запуск обратных кавычек perl

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

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

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


person Dlll    schedule 06.02.2012    source источник


Ответы (4)


Похоже, это хороший вариант использования 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;
}
...
person mob    schedule 06.02.2012
comment
@ikegami - это недокументировано, но если вам нужно знать, вы можете опросить $output->is_ready или проверить $output->{job} (который является Forks::Super::Job объектом) - person mob; 07.02.2012
comment
что касается порядка или завершения, всегда можно использовать функцию «depends_on» в Forks :: Super - person snoofkin; 07.02.2012
comment
@mob, собственно его документы: .. Попытки создать новый процесс. В случае успеха он возвращает объект Forks :: Super :: Job с информацией о ... - person snoofkin; 07.02.2012
comment
@ soulSurfer2010 - depend_on - это ожидание завершения некоторых заданий, прежде чем можно будет начать другое задание - вероятно, здесь бесполезно - person mob; 07.02.2012
comment
@ soulSurfer2010 - В случае успеха возвращает объект Forks :: Super :: Job ... из документации Forks::Super::fork, а не Forks::Super::bg_qx. - person mob; 07.02.2012
comment
Спасибо, это именно то, что я искал. - person Dlll; 10.02.2012

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

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

person Liudvikas Bukys    schedule 06.02.2012

Можно, но без обратных кавычек.

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

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

person Wes Hardaker    schedule 06.02.2012

Вам следует обратиться к FAQ по Perl < / а>.

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

person eyevan    schedule 06.02.2012