ping multiple Ips with python

Branimir Petrovic BranimirPetrovic at yahoo.com
Wed Jan 8 10:43:28 EST 2003


dhostetler at sopris.net (.d.hos) wrote in message news:<8db020b9.0301071301.48472cf5 at posting.google.com>...
> Branimir and everyone who contributed to this thread,
> 
> Thank you...for your patience and knowledge - you have pointed me in
> the right direction.
> 
> Thanks again, .d.hos

"""One last stab at multithreading ping utility:

Windows ping.exe apparently spawns threads that can not run as daemon
threads. Meaning all spawned ping utilities must exit, their processes
must terminate, before Python program that launched them all can
gracefully exit.

Also - the performance difference of threaded v.s. non threaded approach
in pinging network hosts is negligible - meager few percents, not even
five percent in 'real life'. Therefore multithreading 'ping.exe' is
definitely NOT worth the trouble (but playing with and/or testing
Python threading module is;).

Reason for this is that 'multithreaded approach' in this special case
launches ping.exe and actually spawns whole processes via sys.popen
call - each of which takes approx 2.5 MB of RAM and time to set up and
tear down, and all that overhead is what spoils it. Secret here would be
to strike the right amount balance and start only a couple of (but not
too many) concurrent threads.

There is also an issue of DNS name resolving times (should you use fully
qualified host names instead of raw IP addresses) that might have major
impact on overall results. This is another reason why ping.exe utility
is a bad choice for testing Python's abilities to multithread.

I've got a feeling that multithreading I/O bound requests or network
socket programming might be better playing field for stretching/testing
Python's threading 'legs'.

Branimir
"""

import threading, os, Queue, time

def showResponse(args):
    """Pretty prints passed tuple to stdout"""

    ip, stdoutLi, threadName = args
    print '%s \t\t\t\t\t%s\n' % (ip, threadName)

    for line in stdoutLi:
        line = line.strip()
        if not line: continue
        print '\t' + line
    print '='*72

class Pinger(threading.Thread):

    def __init__(self, host, queue):
        threading.Thread.__init__(self)
        self.__host = host
        self.__queue = queue
        self.setDaemon(1)

    def run(self):
        pingCmd = "ping -n 1 -w 1000 " + self.__host
        childStdout = os.popen(pingCmd)
        result = (self.__host, childStdout.readlines(), self.getName())
        childStdout.close()
        self.__queue.put(result)


if __name__ == '__main__':

    # make list of hosts to ping
    hostLi = ["localhost", "66.218.71.83", "64.66.148.171", "127.0.0.1"]

    q = Queue.Queue()

    startA = time.time()
    for host in hostLi:
        """Create and start all necessary threads, passing results
        back via thread safe Queue instance.
        """
        Pinger(host,q).start()

    i = len(hostLi)

    while i > 0:
        """Loop ends when all responses to dispatched pings arrive"""
        showResponse(q.get())
        i -= 1

    endA = time.time()
    totA = endA - startA

    print "Total execution time (using multithreading): \t%s" % (totA,)
    print '*'*72
    print
    print
    print

    startB = time.time()
    for host in hostLi:
        pingCmd = "ping -n 1 -w 1000 " + host
        childStdout = os.popen(pingCmd)
        result = (host, childStdout.readlines(), None)
        childStdout.close()
        showResponse(result)
    endB = time.time()
    totA = endB - startB
    print "Total execution time (WITHOUT multithreading): \t%s" % (totA,)
    print '*'*72




More information about the Python-list mailing list