At 04:07 PM 7/22/02 +0100, Ray Hilton wrote:
>Rather than follow that line of thinking, The objects in question are no
>longer shared, just owned by one thread, and anything wishing to
>communicate with that thread does so through signals. For this, I am
>using Liz's Thread::Queue::Any, which I have literally just started
>looking at and yet to get working.
Well, it should work... ;-) If it doesn't, let me know (which you did,
hope my suggestions worked)...
>The whole point of this is to create a method of dynamically creating
>threads without having to replicate the whole process from the point you
>called the new thread, plus add some other features such as thread
>timeouts and run time. It is quite specific to what we are doing, where
>not all threads are required, but it would be nice to have their
>results, if they take to long, we ignore them and let them finish up in
>their own time.
>Hmm, well, it makes sense to me :)
Makes sense to me too. Maybe this may be of interest to you as an
example. I just finished this for the pod of Thread::Pool 0.17, soon at a
CPAN near you:
--------------------------------------------------------------------------
=head2 simple asynchronous log file resolving filter
This is an example of a very simple asynchronous log file resolver filter.
Because the IP-number to domain name translation is dependent on external
DNS servers, it can take quite some (wallclock) time before a response is
returned by the C<gethostbyaddr> function. In a single threaded environment,
a single bad DNS server can severely slow down the resolving process. In a
threaded environment, you can have one thread waiting for a slow DNS server
while other threads are able to obtain answers in the mean time.
This example uses a shared hash to keep results from DNS server responses,
so that if an IP-number was attempted to be resolved once (either successfully
or unsuccessfully), it will not be attempted again: instead the value from the
hash will be assumed.
# Using Thread::Pool by itself is enough, no "use threads;" needed
# Initialize the shared hash with IP-numbers and their results
use Thread::Pool;
my %resolved : shared;
# Create the pool of threads
my $pool = Thread::Pool->new(
{
workers => 10,
do => \&do,
monitor => \&monitor,
}
);
# Submit each line as a job to the pool
$pool->job( $_ ) while <>;
#--------------------------------------------------------------------
# Handle a single job
# IN: 1 log line to resolve
# OUT: 1 resolved log line
# Substitute the IP-number at the start with the name or with the original
# Return the adapted value
sub do {
$_[0] =~ s#^(\d+\.\d+\.\d+\.\d+)#
$resolved{$1} ||= gethostbyaddr( pack( 'C4',split(/\./,$1)),2 ) || $1#e;
$_[0];
} #do
#--------------------------------------------------------------------
# Output the results in the order they were submitted
# IN: 1 resolved log line
sub monitor { print $_[0] } #monitor
This is a very simple filter. There are a number of drawbacks to this
simplistic approach. They are:
- many more jobs can be added than workers can handle
- multiple threads can be looking up the same IP-number at the same time
but these _can_ be fixed. But they are left as an excercise to the reader.
--------------------------------------------------------------------------
Hope this helps (also)...
Liz