Hi List,
I am trying to create a very simple program using Perl threads. My
test program accepts list of host names from command line, creates a
separate thread for each host name and within the thread, it pings the
given host and stores the result in a shared hash. But this is
giving unpredictable results so far. It seems to be working fine on
Windows 2000 but not on Windows XP.
Any ideas? I am using ActivePerl 5.8.7.
The program listing is given below.
#!/bin/perl -w
#
use strict;
use threads;
use threads::shared;
use Net::Ping;
# Mark this hash sharable by all threads.
my %status : shared;
my $MAX_THREADS = 20;
main();
# returns the total number of threads in the threads list.
sub get_thread_count {
my (@threads);
return(scalar(@threads = threads->list));
}
# if the current number of threads is equal to/greater than the
# predefined limit, then releases the completed threads until the
# running threads becomes less than the maximum limit for threads.
sub wait_for_threads {
my ($thread_count) = @_;
my (@thread_list, $thread);
@thread_list = threads->list;
while (get_thread_count() >= $thread_count) {
$thread = shift(@thread_list);
if ($thread->tid && !threads::equal($thread, threads->self)) {
$thread->join;
}
}
}
sub main {
my ($thread, $host);
while (<>) {
chomp;
threads->new(\&ping_host, $_);
if (get_thread_count() >= $MAX_THREADS) {
print "Max thread limit reached: ", get_thread_count(), "\n";
wait_for_threads($MAX_THREADS - 10);
}
}
# wait for all the currently running threads to finish.
foreach $thread (threads->list) {
# Main thread has a thread id of zero. Skip the main thread
# and this thread while joining.
if ($thread->tid && !threads::equal($thread, threads->self)) {
$thread->join;
}
}
# at this point, all the threads have finished and the result is
# in the hash. Print the status by looping thru the keys.
foreach $host (sort keys %status) {
print "$host is $status{$host}.\n";
}
}
sub ping_host {
use Net::Ping;
my ($host) = @_;
my ($p, $result);
$p = Net::Ping->new();
$result = ($p->ping($host)) ? "alive" : "unreachable";
$p->close();
# good idea to lock the hash before making modification
lock(%status);
$status{$host} = $result;
}
Thanks,
with warm regards,
Venkat Saranathan.