Okay. On the basis of the (still scant) specification provided, this is how I would prototype that application. You'll see that I've dodged the issue of the shared hash and locking all together by using a queue:
# perl -slw
use strict;
use Time::HiRes qw[ time sleep ];
use threads;
use threads::shared;
use Thread::Queue;
$|++;
my $SOsem : shared;
sub tprintf {
lock $SOsem;
printf "[%3d]" . $_[ 0 ], threads->tid, @_[ 1 .. $#_ ];
}
sub tprint {
lock $SOsem;
printf "[%3d] %s" . $/, threads->tid, join ', ', @_;
}
sub gatherer {
my $tid = threads->tid;
my( $Q, $stop, $interval ) = @_;
while( !$$stop ) {
## Get dataset
my @data :shared = ( $tid, time(), map int( rand 100 ), 1 .. 5
+ );
$Q->enqueue( \@data );
sleep $interval;
}
}
sub sender{
my $tid = threads->tid;
my( $Q, $stop, $interval ) = @_;
while( sleep $interval ) {
my $available = $Q->pending;
last if $$stop and !$available;
next unless $available;
my @datasets;
push @datasets, [ @{ $Q->dequeue } ] for 1 .. $available;
## 'send' the data
tprint "\n", time();
tprint "@$_" for @datasets;
}
}
our $GATHERERS ||= 5;
our $INTERVAL ||= 15;
our $GINTERVAL ||= $INTERVAL;
my $Q = new Thread::Queue;
my $stop :shared = 0;
$SIG{ INT } = sub { $stop = 1 };
threads->create( \&gatherer, $Q, \$stop, $GINTERVAL )->detach
for 1 .. $GATHERERS;
my $sender = threads->create( \&sender, $Q, \$stop, $INTERVAL )->join;
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
|