Perl Многопоточность не работает пакетная команда - PullRequest
0 голосов
/ 28 февраля 2019

Я пытаюсь использовать perl многопоточность для выполнения каждой из команд cmd.exe, содержащихся в большом файле, подобном следующему:

copy file1.txt file2.txt
copy file3.txt file4.txt
...
copy file5000.txt file5001.txt

Я посмотрел на ответ на thisвопрос и пробовал пример теста для копирования только двух файлов.

Проблема в том, что команда никогда не вызывается.Он никогда не копирует файлы, даже если они находятся там и в той же папке, где я запускаю скрипт perl.

Что я делаю не так?

use strict;
use warnings;
use threads;
use Thread::Queue; 

print "Perl Starting ... \n\n"; 

my $q = Thread::Queue->new();    # A new empty queue

# Worker thread
my @thrs = threads->create(\&doOperation ) for 1..5;#for 5 threads

my @files = ("copy file123.xml test1.xml", "copy file123.xml test2.xml");
#add files to queue
foreach my $f (@files){
  # Send work to the thread
  $q->enqueue($f);
  print "Pending items: ". $q->pending() ."\n";
}
$q->enqueue('_DONE_') for @thrs;
$_->join() for @thrs;



sub doOperation () {
    my $ithread = threads->tid() ;
    while (my $cmd = $q->dequeue()) {
      # Do work on $item

      print "cmd: $cmd ... \n";
      print "Running Dos command ... \n";

      my $status = system("$cmd");

      print "Status: $status ... \n";
      print "End Dos command ... \n";

      return 1 if $cmd eq '_DONE_';
      print "[id=$ithread]\t$cmd\n";
    }
    return 1;
}


print "\nPerl End ... \n\n"; 

… и вотвыход в cmd.exe

Perl Starting ...

Pending items: 1
cmd: copy file123.xml test1.xml ...
Running Dos command ...
Pending items: 0
cmd: copy file123.xml test2.xml ...

Running Dos command ...
Perl End ...

Perl exited with active threads:
        5 running and unjoined
        0 finished and unjoined
        0 running and detached

PS.Я уже попробовал Parallel :: ForkManager, и он продолжает зависать после X числа обработки на моем сервере Windows, поэтому я ищу альтернативное решение.

1 Ответ

0 голосов
/ 28 февраля 2019

Следующее объявление приводит к тому, что @thrs имеет нулевые элементы.

my @thrs = threads->create(\&doOperation ) for 1..5;#for 5 threads

Затем вы ссылаетесь на @thrs в двух местах.Если вы замените все эти ссылки на threads->list(), как указывает Мобрин (не только одна ссылка, а две), то вы добьетесь прогресса.

Или вы можете исправить объявление следующим образом:

my @thrs;
push @thrs, threads->create(\&doOperation ) for 1..5;

Относительно вашего комментария на ваш вопрос об исправлении одной ссылки, позволяющей выполнять копии, но не о завершении скрипта: вы, вероятно, не исправили вторую ссылку, которая ставит в очередь DONE, предотвращая прерывание каждым потоком своего цикла while.


В своем комментарии ниже и в предположении, что вам нужно вести собственный список тем, ikegami показывает более изощренный способ создания списка:

my @thrs = map { threads->create(\&doOperation ) } 1..5;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...