ping multiple Ips with python

Gerhard Haering gerhard.haering at gmx.de
Fri Jan 3 22:22:38 EST 2003


* darrell <dgallion1 at yahoo.com> [2003-01-04 03:07 +0000]:
> Multiple ping sounded like fun.

Indeed :)

> So here's a quick mod to some ping code I found.

I'll try to look at it. I've meanwhile come up with this piece of code
(unfortunately I can't sucessfully kill the pings, the os.kill only kills the
'sh' processes from popen2.Popen3:

If nothing else, the original poster might benefit from the example of using
Queue.Queue with *one* database logger thread.

#v+
import threading
import os, popen2, select, signal
import Queue
import time

from pyPgSQL import PgSQL

# (PostgreSQL) database schema:
# CREATE TABLE LOG(ADDRESS INET, UP BOOL);

HOST_UP = 1
HOST_DOWN = 0

PING_INTERVAL = 5

def log(s):
    print s

class Pinger(threading.Thread):
    def __init__(self, queue, address, *args, **kwargs):
        self.address = address
        self.queue = queue
        threading.Thread.__init__(self, *args, **kwargs)
        self.stop = 0

    def run(self):
        child = popen2.Popen3("ping -i %i %s 2>&1" % (PING_INTERVAL, self.address))
        log("started child %i" % child.pid)
        while 1:
            ready_fds = select.select([child.fromchild], [], [])

            line = child.fromchild.readline()
            if line.find("Host is down") >= 0:
                log("host %s is down" % self.address)
                self.queue.put((self.address, HOST_DOWN))
            else:
                log("host %s is up" % self.address)
                self.queue.put((self.address, HOST_UP))
            
            if self.stop:
                os.kill(child.pid, signal.SIGTERM)
                log("killed child %i." % child.pid)
                break

class DbLogger(threading.Thread):
    def __init__(self, queue, *args, **kwargs):
        self.stop = 0
        self.queue = queue
        threading.Thread.__init__(self, *args, **kwargs)

    def run(self):
        con = PgSQL.connect()
        cursor = con.cursor()
        while 1:
            if self.stop:
                con.close()
                break

            item = self.queue.get()
            cursor.execute("INSERT INTO LOG(ADDRESS, UP) VALUES (%s, %s)",
                (item[0], PgSQL.PgBoolean(item[1])))
            con.commit()
            log("committed.")

def main():
    pinglist = ["127.0.0.1", "192.168.0.1", "192.168.2.1", "192.168.2.10", "192.168.2.11"]
    threads = []
    queue = Queue.Queue()
    for adr in pinglist:
        threads.append(Pinger(queue, adr))

    threads.append(DbLogger(queue)) 

    for thread in threads:
        thread.start()

    try:
        while 1:
            time.sleep(1)
            log("in main loop.")
    except KeyboardInterrupt:
        pass

    for thread in threads:
        thread.stop = 1

    for thread in threads:
        thread.join(2.0)

    # Ok, I've had enough of you stupid threads.
    os._exit(0)

if __name__ == "__main__":
    main()
#v-

If you try this out and are annoyed by the remaining 'ping' processes, here's a
quick *cough* solution ;-)

#v+
import os, signal, commands

s = commands.getoutput("ps aux|grep ping|grep -v grep")
for line in s.split("\n"):
    pid = int(line.split()[1])
    os.kill(pid, signal.SIGKILL)
#v-

Gerhard
-- 
Favourite database:             http://www.postgresql.org/
Favourite programming language: http://www.python.org/
Combine the two:                http://pypgsql.sf.net/
Embedded database for Python:   http://pysqlite.sf.net/





More information about the Python-list mailing list