2013-04-30 2 views
0

Я пытаюсь получить текст из двух больших файлов. Чтобы ускорить это, я попробовал потоки. Прежде чем я использовал потоки, скрипт работал, а теперь нет.Perl: записать значение в потоке

Проблема в следующем: я сохраняю все, что я прочитал в файле, в хэш. Когда я распечатываю размер (или клавиши/значения) после чтения в суб (который выполняется нить), он показывает правильное число> 0, когда я печатаю размер хэша в другом месте (после потоков пробег), это показывает мне 0.

print ": ".keys(%c); 

используется 2 раза, и каждый раз имеет разную мощность. (В финальной программе 2 потоков выполняются и способ, чтобы сравнить материал вызывается после нити законченный)

Пример кода:

my %c; 
    my @threads = initThreads(); 

    @threads[0] = threads->create(\&ce); 

foreach(@threads){ 
    $_->join(); 
} 
print ": ".keys(%c); 


sub initThreads{ 
    my @initThreads; 

    for(my $i = 0; $i<2;$i++){ 
      push(@initThreads, $i); 
    } 
return @initThreads; 
} 

sub ce(){ 
    my $id = threads->tid(); 

    open my $file, "<", @arg1[1] or die $!; 

    my @cXY; 
    my @cDa; 

    while(my $line = <$file>){ 

# some regex and push to arrays, works 
      @c{@cXY} = @cDa; 

    } 

    print "Thread $id is done\n"; 
    close $file; 

print ": ".keys(%c); 
    threads->exit(); 
} 

Должен ли я запускать вещи после первых 2-х нитей закончен в другом потоке, который ждет, пока первые два не закончатся? Или что я делаю неправильно с потоками?

Спасибо.

ответ

1

%c не поделился нитью.

use threads; 
use threads::shared 

my %c :shared; 

См. threads::shared.

+0

Спасибо, это сработало. К сожалению, это не быстрее, чем чтение в файлах один за другим, это даже намного медленнее ... – user1203092

+0

Быстрее ли это в несетевой версии с несколькими версиями (даже если это неверно)? Обмен данными имеет свои затраты. Хеш заблокирован каждый раз, когда он доступен; вы фактически блокируете другие потоки, когда это происходит. Возможно, вы захотите попробовать подход в другом ответе, который предлагает вернуть данные из потока. Это полностью изолирует потоки. –

1

В Perl потоки не разделяют память. Каждый поток работает с другой копией %c, поэтому изменения не отражаются на родительском потоке. Хотя обмен переменной по потокам возможен, это обычно не рекомендуется.

Использовать возможность для return данные из нити. Например

my %c = map %{ $_->join }, @threads; # flatten all returned hashes 

sub ce { 
    my %hash; 
    ...; 
    return \%hash; 
} 

Некоторые другие предложения:

  • use strict; use warnings;, если вы еще не.
  • использовать имена переменных.
  • Вы только, кажется, не размножаетесь ниткой (в $threads[0]).
  • my @array; for (my $i = 0; $i < 2; $i++){ push(@array, $i) } эквивалентен my @array = 0 .. 1.
  • @arg1 не указан в текущей области.
  • ручное управление exit В вашем случае нить не обязательна.
+0

Спасибо за предложения, я уже делаю почти все, что вы написали, я просто не хотел копировать весь скрипт. Я не знал, что выход здесь не обязательно. – user1203092

Смежные вопросы