in reply to Re: Multi-thread combining the results together
in thread Multi-thread combining the results together

Thank you very much!

I did have to merge some of your ideas together with TreadQueue.
My code works and is 3+x faster with 4 threads. That is about what I expected in terms of performance increase.

Thanks again - your code is much clearer than the Perl Doc and is a much easier to follow set of model code.

Update: some code:

#!/usr/bin/perl use strict; use warnings; use threads; use Thread::Queue; $|=1; use CQP_SearchPatterns; my $t = time(); ## start run time my @logs = <*.log>; print "number of logs: ".@logs,"\n"; my %Rcall_histo; my $tot_qs=0; foreach my $this_log (@logs) { open IN, '<', $this_log or die "bogus log file $!"; my $nqso=0; while (my $line= <IN>) { next unless $line =~ /^QSO:/; $nqso++; my ($RcvdCall) = (split ' ', $line)[8]; #9th thing in QSO: $RcvdCall = uc $RcvdCall; $Rcall_histo{$RcvdCall}++; } print "$nqso\t$this_log\n"; $tot_qs += $nqso; } close IN; print "total q's = $tot_qs\n"; print "total calls = ".keys %Rcall_histo,"\n"; my @all_calls = sort keys %Rcall_histo; open OUT, '>', "CQWW_ApproxTest.txt" or die "unable to open CQWW_Appro +xTest.txt $!"; my $workQueue = Thread::Queue->new(); # A new empty queue for work (t +he callsigns) my $doneQueue = Thread::Queue->new(); # A new empty queue for output +(the approx calls) ### Worker threads ##### my $thread_limit = 4; my @threads; push @threads, threads->create(sub{DoWork($workQueue, $doneQueue)}) fo +r 1 .. $thread_limit; foreach my $call ( @all_calls ) #init the work queue with all callsig +ns { $workQueue->enqueue($call); } $workQueue->enqueue(undef) for 1 .. $thread_limit; #"work finished" m +arkers #each thread will +give up #when it sees an u +ndef $workQueue->end(); $_->join() for @threads; print "END of threading...\n"; my @results; while ($doneQueue->pending() && ($_ = $doneQueue->dequeue()) ) { push (@results, $_); #results are pointers to array (AoA) } my $end_time = time(); my $elasped_time = $end_time- $t; print "elaspsed time = $elasped_time\n"; print "elaspsed time = ", $elasped_time/60, " minutes\n"; @results = sort{$a->[0] cmp $b->[0]}@results; print OUT "@$_\n" for @results; sub DoWork { my ($workQueue, $doneQueue) = @_; while (my $call = $workQueue->dequeue()) { return unless defined ($call); #this ends this thread's job if ($call =~ m|/|) { $doneQueue -> enqueue([$call,'SKIP portable callsign!']); next; } my $regex = get_regex_patterns ($call); $regex =~ s/\(|\)//g; #captured values not needed, only yes/no my @matches = grep{ m/$regex/ and $_ ne $call}@all_calls; push (@matches,'') if @matches==0; if (@matches>20 and $call =~ /\d[A-Za-z]$/) #ends in single Alp +ha char { @matches = @matches[0..19]; $doneQueue -> enqueue([$call,"TRUNCATE",@matches]); } else { $doneQueue -> enqueue([$call,@matches]); } # print "$call @matches\n"; #debug for threads ==1 } }