основная программа Perl ждет вечно - PullRequest
0 голосов
/ 06 мая 2018

Я относительно новичок в Perl, и я написал программу для обработки тех же операций на множестве образов ОС. Поскольку операции были одинаковыми, я использовал потоки. Уменьшенная версия программы прилагается. Проблема в том, что основная программа никогда не выходит и ждет вечно. По трассировке вижу, что основная программа ждет по команде "тройник". Что-нибудь, что я тут натворил?

Я нахожусь на CentOS 6.7 с Perl версии 5.1, и я не могу двигаться вперед из-за многих других зависимостей: (* ​​1003 *

#!/usr/bin/perl -w
use threads;


my $tee_pid= open my $tee, "|-", "tee mylog";
my @images = ( "image1" , "image2");

foreach my $image (@images){
$_ = async { do_ops_on_image() };
sleep ( 60 );
}

while( threads->list ) {
    for my $joinable ( threads->list( threads::joinable ) ) {
        $joinable->join;
    }
}
print "All thread completed \n";
close $tee;

sub do_ops_on_image
{
  my $time = `date`;
  my $id = threads->tid();
  sleep (120) if ( $id ==2 );
  print $tee "my $id started at $time \n";
}

Ответы [ 2 ]

0 голосов
/ 06 мая 2018

Я относительно новичок в Perl […] Я использовал темы.

Это ваша проблема.

Темы Perl странные . У них есть ряд неожиданных и нежелательных поведений; в частности, большинство переменных невозможно безопасно разделить между потоками, а некоторые модули вообще не поддерживают использование в многопоточной среде. Цитировать документацию threads :

«Основанные на интерпретаторе потоки», предоставляемые Perl, не являются быстрой и легкой системой многозадачности, на которую можно ожидать или на которую можно надеяться. Потоки реализованы таким образом, что их легко использовать неправильно. Мало кто знает, как правильно их использовать, или сможет оказать помощь.

Официально не рекомендуется использовать потоки на основе интерпретатора в Perl.

Для многих распространенных применений модуль Parallel::ForkManager может быть более подходящим выбором.

0 голосов
/ 06 мая 2018

Это похоже на ошибку в perl, которая была исправлена ​​в версии 5.14.0. Если вы действительно не можете установить более новый perl (в дополнение к системному perl), попробуйте избежать общего файлового дескриптора $ tee, из-за которого основной поток зависает.

Кроме того, ваш код для ожидания завершения дочерних потоков использует активный цикл ЦП, который сожжет много ЦП. Если вы просто хотите дождаться завершения всех дочерних потоков, сделайте что-то вроде

my @threads;
...
for ... {
     push @threads, async { ... }
}
...
$_->join for @threads;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...