2015-06-26 4 views
1

У меня есть следующий код Perl ::Perl Thread прирастить переменной

#!/usr/bin/perl 

use threads; 
use Thread::Queue; 
use DateTime; 

$| = 1; my $numthreads = 20; 

$min = 1; 
$max = 100; 

my $fetch_q = Thread::Queue->new(); 
our $total = 0; 
sub fetch { 
    while (my $target = $fetch_q->dequeue()) { 
      print $total++ . " "; 
    } 
} 

my @workers = map { threads->create(\&fetch) } 1 .. $numthreads; 

$fetch_q->enqueue($min .. $max); 
$fetch_q->end(); 

foreach my $thr (@workers) {$thr->join();} 

код создает 20 потоков, а затем увеличивает значение переменной $total.

Ток на выходе что-то вроде:

0 0 0 0 0 1 0 0 1 1 2 0 0 1 0 2 0 3 0 1 0 2 1 0 2 1 0 0 3 0 

Но желаемый результат:

1 2 3 4 5 6 7 8 9 10 .... 30 

Есть ли способ иметь Perl увеличиваем переменную? Порядок не имеет значения (т. Е. Его штраф, если он равен 1 2 4 5 3).

+0

Вы должны сделать [атомарной операции] (http://stackoverflow.com/questions/13040333/what-perl-built- in-functions-are-atomic), или результаты будут полностью сумасшедшими. – tadman

+2

Вы всегда должны *** использовать «строгое» и «использовать предупреждения» в верхней части каждой программы Perl, которую вы пишете. Является бесценной мерой, которая быстро выделит многие простые ошибки, которые вы можете упускать из виду. – Borodin

+0

Я всегда использую это. Для этого я хотел сохранить свой тестовый файл для SO как можно меньше. – Bijan

ответ

5
use threads::shared; 

my $total :shared = 0; 

lock $total; 
print ++$total . " ";