| Venkatesan Saranathan 2005-12-12, 7:27 pm |
| 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 =3D 20;
main();
# returns the total number of threads in the threads list.
sub get_thread_count {
my (@threads);
return(scalar(@threads =3D 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) =3D @_;
my (@thread_list, $thread);
@thread_list =3D threads->list;
while (get_thread_count() >=3D $thread_count) {
=09$thread =3D shift(@thread_list);
=09if ($thread->tid && !threads::equal($thread, threads->self)) {
=09 $thread->join;
=09}
}
}
sub main {
my ($thread, $host);
while (<> ) {
=09chomp;
=09threads->new(\&ping_host, $_);
=09if (get_thread_count() >=3D $MAX_THREADS) {
=09 print "Max thread limit reached: ", get_thread_count(), "\n";
=09 wait_for_threads($MAX_THREADS - 10);
=09}
}
# wait for all the currently running threads to finish.
foreach $thread (threads->list) {
=09# Main thread has a thread id of zero. Skip the main thread
=09# and this thread while joining.
=09if ($thread->tid && !threads::equal($thread, threads->self)) {
=09 $thread->join;
=09}
}
# 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) {
=09print "$host is $status{$host}.\n";
}
}
sub ping_host {
use Net::Ping;
my ($host) =3D @_;
my ($p, $result);
$p =3D Net::Ping->new();
$result =3D ($p->ping($host)) ? "alive" : "unreachable";
$p->close();
# good idea to lock the hash before making modification
lock(%status);
$status{$host} =3D $result;
}
Thanks,
with warm regards,
Venkat Saranathan.
|