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

Reply via email to