1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
|
# $Id: Threaded.pm,v 1.4 2004/10/16 21:13:28 jfontain Exp $
package Threaded; # sample/template for a non-blocking Perl module using threads
use threads;
use Thread::Queue;
use strict;
use warnings;
BEGIN {
our $VERSION = qw($Revision: 1.4 $)[1];
}
our $in = Thread::Queue->new(); # data generated from the thread
our $out = Thread::Queue->new(); # data fed to the thread
sub work() { # collect and possibly process data inside a thread
while (my $value = $in->dequeue()) {
# simulate processing or potentially blocking operations
# for (my $i = 0; $i < $value; $i++) {} # processing (use large value)
sleep(1 + int(rand($value))); # or blocking
$out->enqueue(rand(100)); # simulate gathered data
yield('updated'); # give control back to the core which calls updated()
# Note: this is required as the parent Perl interpreter is no longer
# running at this time, and thus needs to be awaken by the application
# core, which is always running.
# Note: yield(), along with the after(), flashMessage(), pushMessage(),
# popMessage() and traceMessage() subroutines are defined by the core in
# the module namespace and therefore should be seen as reserved
# subroutines, not to be redefined in the module (this file for the
# Threaded module).
}
}
our %data;
our @data;
our $asynchronous;
$data{updates} = 0;
$data{columns}[0] = {label => '', type => 'ascii', message => ''}; # hidden
$data{columns}[1] = {label => 'data', type => 'integer', message => 'value'};
$data{pollTimes} = [5, 1, 2, 10, 20, 30, 60, 120, 300];
$data{views} = [{indices => [1], sort => {1 => 'increasing'}}];
$data{persistent} = 1;
$data{switches} = {'-a' => 0, '--asynchronous' => 0};
$data[0][0] = '';
$data{helpText} = `cat Threaded.htm`; # load HTML formatted help
sub initialize(%) {
my %option = @_;
$asynchronous = (($option{'-a'} || $option{'--asynchronous'}));
threads->new(\&work); # create thread blocked waiting on queue for now
if ($asynchronous) {
$data{pollTimes} = [-2]; # update every 2 seconds on average
$in->enqueue(3); # start thread action
}
}
our $busy; # whether the worker thread is busy processing
# note: the updated() subroutine is mandatory in threaded modules
sub updated() { # possibly process data from the thread and trigger core update
$data[0][1] = $out->dequeue();
$data{updates}++;
$busy = 0; # ready for more data collection and processing
if ($asynchronous) {
$in->enqueue(3); # start thread action
}
}
sub update() {
if ($busy) {return};
$busy = 1;
$in->enqueue(3); # start thread action
}
1;
|