Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

Re: Multi-threading ping of a list of hosts.....Again!

by NetWallah (Abbot)
on Sep 20, 2004 at 17:28 UTC ( #392426=note: print w/ replies, xml ) Need Help??


in reply to Multi-threading ping of a list of hosts.....Again!

Here is some working multi-threaded ping code I wrote a while back. Works on Win32.

#!/usr/bin/perl -w # Parallel Pinger... use strict; use threads; use Thread::Queue; use Net::Ping; my $master = $$; my $verbose = $ARGV[0] eq q(-v); my $RequestQ = Thread::Queue->new; my $ResultQ = Thread::Queue->new; my $threadcount = 20; my @kids; # Generate list of hosts to ping my @targets; foreach my $target (1..95) { $RequestQ->enqueue ('10.2.56.' . $target); } for (0..($threadcount - 1)){ $RequestQ->enqueue(undef); push @kids, threads->new(\&Ping_it, $_); } foreach (threads->list){ $_->join; } $ResultQ->enqueue(undef); # Last item while (my $target = $ResultQ->dequeue){ print " $target\n"; } ############################################# sub Ping_it{ my ($work_count, $miss_count); my $t = shift; my $pinger = Net::Ping->new('icmp', 1); while (my $target = $RequestQ->dequeue){ $work_count ++; my $retval = 0; $verbose and print "Child $target started\n"; if($pinger->ping($target)) { # PING! Throw it in the FIFO $verbose and print "Found $target!\n"; $retval=1 } else { warn "Thread $t $target: $!\n"; $verbose and print "No response from $target\n"; $retval=0; $miss_count++; } $ResultQ->enqueue ($target . "=" . $retval); threads->yield(); $verbose and print "Child $target exiting\n"; } $pinger->close(); $ResultQ->enqueue("Thread $t processed $work_count, missed $miss_co +unt"); }

    Earth first! (We'll rob the other planets later)


Comment on Re: Multi-threading ping of a list of hosts.....Again!
Download Code
Re^2: Multi-threading ping of a list of hosts.....Again!
by BrowserUk (Pope) on Sep 20, 2004 at 19:03 UTC

    A couple of questions about your code:

    1. Why accumulate your thread handles into @kids when you never use them again?
    2. Why not detach the threads at creation when you don't use the returns?

    Please note. There is no implied critism here, just comparing notes.

    FWIW, I like your technique of enqueuing undefs to terminate your loops. It's much cleaner than several things I've used.


    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "Think for yourself!" - Abigail
    "Memory, processor, disk in that order on the hardware side. Algorithm, algorithm, algorithm on the code side." - tachyon
      I sort of "converted" someone elses program model, and never cleaned it up after proving that it worked , so it has leftover junk. Since this was just a "test program", I did not bother to do the cleanup, so, points taken. Thanks.

          Earth first! (We'll rob the other planets later)

Re^2: Multi-threading ping of a list of hosts.....Again!
by blackadder (Hermit) on Sep 23, 2004 at 10:21 UTC
    All my hosts are Netbios names. Do I have convert them to an IP address instead to use it in this script?

    Thanks
Re^2: Multi-threading ping of a list of hosts.....Again!
by blackadder (Hermit) on Sep 23, 2004 at 11:07 UTC
    Not Sure if it worked or not!

    I modified the script to;
    use strict; use Win32; use Win32::AdminMisc; use threads; use Thread::Queue; use Net::Ping; my $master = $$; my $verbose = $ARGV[0] eq q(-v); my $RequestQ = Thread::Queue->new; my $ResultQ = Thread::Queue->new; my $threadcount = 20; my @kids; my @targets; while (<DATA>) { chomp; print "$_ : "; my $ip_address = Win32::AdminMisc::gethostbyname($_); print "$ip_address\n"; push (@targets, $ip_address); } # Generate list of hosts to ping foreach my $target (@targets) { $RequestQ->enqueue ($target); } for (0..($threadcount - 1)){ $RequestQ->enqueue(undef); push @kids, threads->new(\&Ping_it, $_); } foreach (threads->list){ $_->join; } $ResultQ->enqueue(undef); # Last item while (my $target = $ResultQ->dequeue){ print " $target\n"; } ############################################# sub Ping_it{ my ($work_count, $miss_count); my $t = shift; my $pinger = Net::Ping->new('icmp', 1); while (my $target = $RequestQ->dequeue){ $work_count ++; my $retval = 0; $verbose and print "Child $target started\n"; if($pinger->ping($target)) { # PING! Throw it in the FIFO $verbose and print "Found $target!\n"; $retval=1 } else { warn "Thread $t $target: $!\n"; $verbose and print "No response from $target\n"; $retval=0; $miss_count++; } $ResultQ->enqueue ($target . "=" . $retval); threads->yield(); $verbose and print "Child $target exiting\n"; } $pinger->close(); $ResultQ->enqueue("Thread $t processed $work_count, missed $miss_co +unt"); } __DATA__ SN02GEY10a SN02GEZ10a SN02GFC09a SN02GEY09a SN02GEZ09a SN02GEY05a SN02GEY06a SN02GEY07a SN02GEY08a SN02GEZ05a SN02GEZ06a
    And the output was;
    C:\Perl>ping_sweep2.pl SN02GEY10a : 172.24.175.53 SN02GEZ10a : 172.24.166.15 SN02GFC09a : 172.24.184.43 SN02GEY09a : 172.24.184.21 SN02GEZ09a : 172.24.175.10 SN02GEY05a : 172.24.166.48 SN02GEY06a : 172.24.175.43 SN02GEY07a : 172.24.184.12 SN02GEY08a : 172.24.166.13 SN02GEZ05a : 172.24.175.55 SN02GEZ06a : 172.24.184.46 172.24.175.53=1 172.24.166.15=1 172.24.184.43=1 172.24.175.10=1 172.24.184.21=1 172.24.166.48=1 172.24.175.43=1 Thread 4 processed , missed 172.24.184.12=1 172.24.175.55=1 172.24.166.13=1 172.24.184.46=1 Thread 1 processed 3, missed Thread 2 processed 3, missed Thread 0 processed 3, missed Thread 3 processed 2, missed Thread 5 processed , missed Thread 6 processed , missed Thread 7 processed , missed Thread 8 processed , missed Thread 9 processed , missed Thread 10 processed , missed Thread 11 processed , missed Thread 12 processed , missed Thread 13 processed , missed Thread 14 processed , missed Thread 15 processed , missed Thread 16 processed , missed Thread 17 processed , missed Thread 18 processed , missed Thread 19 processed , missed
    Do I have to convert the hostnames to IP address first?Any thoughts on how to get it working fully please?

    Thanks
    Blackadder
      Looks like it DID work. You successfully pinged 12 hosts.

      To get the "verbose" output, run it like this:
      >ping_sweep2.pl -v

           Re:Do I have to convert the hostnames to IP address first?Any

      From the Net::Ping FM:
      $host can be either the hostname or the IP number of the remote host

      You should also be able to collapse some of the code like so (untested):

      ##Replace THIS code while (<DATA>) { chomp; print "$_ : "; my $ip_address = Win32::AdminMisc::gethostbyname($_); print "$ip_address\n"; push (@targets, $ip_address); } # Generate list of hosts to ping foreach my $target (@targets) { $RequestQ->enqueue ($target); } ## Replace with THIS code #### while (<DATA>) { chomp; print "Queuing ping for $_ : "; $RequestQ->enqueue $_ ; # Feed the NAME directly in }

          Earth first! (We'll rob the other planets later)

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://392426]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others musing on the Monastery: (8)
As of 2014-08-22 11:25 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The best computer themed movie is:











    Results (156 votes), past polls