You might to check out Thread::Running on CPAN, which is based on Thread::Exit, which you also might find interesting.

At 8:21 AM -0700 3/6/06, Jerry D. Hedden wrote:
First of all, the 'Thread' module is defunct.  Use the 'threads' module
instead.

There is no ->done() method.  You have to simulate it using a shared
variables to convey thread status back to the parent thread.

Here is a working example that should contain all the elements you need:

#!/usr/bin/perl

use strict;
use warnings;

use threads;
use threads::shared;

### Global Variables ###

my $MAX_THREADS = 10;
# Shared array for signalling that threads are done
my @THREAD_DONE :shared;

# End this test with ^C or kill
my $TERMINATE = 0;
$SIG{'INT'} = $SIG{'TERM'} =
    sub {
        print("Terminating\n");
        $TERMINATE = 1;
    };

### Main Processing Section ###
MAIN:
{
    # Initialize with bogus IDs
    @THREAD_DONE = (-1) x $MAX_THREADS;

    # Do lots of work
    while (! $TERMINATE) {
        # Check all the threads
        for (my $tt=0; $tt < $MAX_THREADS; $tt++) {
            # Is the thread done?
            if (my $tid = $THREAD_DONE[$tt]) {
                # Get the thread object and join to it
                if (my $thr = threads->object($tid)) {
                    $thr->join();
                }
                # Clear the done flag
                $THREAD_DONE[$tt] = 0;
                # Launch a new thread with its ID as the first arg
                threads->new(\&worker, $tt);
            }
            # Pause before checking again
            sleep(1);
        }
    }

    # Wait for all threads to finish
    while (@THREAD_DONE) {
        for (my $tt=0; $tt < $MAX_THREADS; $tt++) {
            # Is the thread done?
            if (my $tid = $THREAD_DONE[$tt]) {
                # Get the thread object and join to it
                if (my $thr = threads->object($tid)) {
                    $thr->join();
                }
                # Purge entry from done signalling array
                delete($THREAD_DONE[$tt]);

            } elsif (defined($THREAD_DONE[$tt])) {
                # Purge (0) entry from done signalling array
                delete($THREAD_DONE[$tt]);
            }
            # Pause before checking again
            sleep(1);
        }
    }
}

print("Done\n");
exit(0);

### Subroutines ###

sub worker
{
    # Get my ID
    my $id = shift;

    # Do some work
    print("Working -> $id\n");
    sleep(5 + int(rand(10)));   # Working hard, or hardly working?
    print("           $id <- Finished\n");

    # Signal that I am done using my TID
    $THREAD_DONE[$id] = threads->self()->tid();
}

# EOF

Reply via email to