xaero123 has asked for the wisdom of the Perl Monks concerning the following question:
But when I try to use it, sometimes I get an infinite output, or strange output in console, like:use threads; use threads::shared; my @block : shared; # block of data my $pos : shared; # offset in data-file here my $threadscnt=30; # count of threads open INFH, '<', $path.'list.txt' or die("Cannot open list.txt : $!\n") +; # file with input data $listsize = -s INFH; binmode(INFH); $pos=0; for(0..abs($threadscnt-1)){ $trarr[$_]=threads->create(\&smeacts, $_); + } for(@trarr){$_->join; } sub smeacts($) { my $num = shift(@_); until(($pos>=$listsize)and((scalar @block)==0)){ # until we reached th +e end of datafile if (@block){ { lock(@block); $sline = shift(@block); } # get line of data and lock +block from other threads to prevent errors print "from $num: $sline($pos,$listsize)\n"; sleep(rand(5)); } # emula +te some work with data if ((scalar @block)==0){ async{ getnewblock(); } } # get new block if +necessary } } print 'end.'; sub getnewsline() { my $oneline=''; my $tmp=''; while((read(INFH, $tmp, 1))and(not(($tmp eq "\n")or($tmp eq "\r")))){ +# binary reading line of data $oneline .= $tmp; $pos++; } $pos++ if ($tmp eq "\n"); # for unix new-line format if ($tmp eq "\r"){ seek(INFH, 1, 1); $pos += 2; } # for win new-line f +ormat return $oneline; } sub getnewblock() { my $i=0; my $tmp = getnewsline(); while(($i<=abs($threadscnt-1))and($tmp)){ push(@block, $tmp); $i++; $tmp = getnewsline(); } return; }
Why it happens? Using async and lock didnt fixed the problem, as I saw. I think that the problem is in shared access, or access to line in one time... But sometimes this program gives me the perfect output, just as I expected, and sometimes some 'madness'. For info, I am using ActivePerl 5.10.1. Remember, that sometimes it gives the CORRECT output, but if you make more tests - you will see what I said! Now, what can you correct or suggest to fix this unstability? Sorry for my mistakes in English, it is not my native language.from 1: foo(45,999) from 2: bar(48,999) from 3: foo(45,999) ... from 8: a(1050,999)
|
|---|