2012-02-06 2 views
4

Сейчас у меня есть скрипт на языке Perl, который в определенный момент, собирает и обрабатывает выходные данные из нескольких команд Баша, сейчас вот как я сделал это:Асинхронных работают обратные кавычки в Perl

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

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

ответ

3

Это звучит как хороший вариант использования для 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; 
... 

Update 2012-03-01: v0.60 Форкс :: Супер has some new constructions, которые позволяют получать результаты в контексте списка:

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; 
} 
... 
+0

Как вы знаете, какая команда заканчивается первый? – ikegami

+0

@ikegami - Это недокументировано, но если вам нужно знать, вы можете опросить '$ output-> is_ready' или проверить' $ output -> {job} '(который является объектом' Forks :: Super :: Job') – mob

+0

о заказе или завершении, всегда можно использовать функцию «depend_on» Forks :: Super – snoofkin

2

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

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

Есть несколько классов в CPAN, которые, вероятно, уже справляются с некоторой сложностью для вас.

4

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

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