PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Python - Thread funktioniert nicht!



TheGrudge
12-10-2005, 10:24
Hallo,

ich lerne gerade ein bisserl Python und wollte nun mal ein Beispiel mit Threads ausprobieren.
Da ist ein Programm, das mittels einer for-Schleife einen IP-Bereich überprüft per ping und aufgrund einer RegEx eine Statusmeldung ausgibt.

Lasse ich das Programm ohne Threads laufen, funktioniert es, dauert so an die 2 Minuten.

Nun soll in dem Tutorial eine Klasse erstellt werden, die von "Thread" abgeleitet wird, angeblich dauert das Programm dann nur noch 20 Sekunden.

Aber leider hängt sich Python nach dem ersten Ping immer auf und ich muss alle übrigen Pings per
killall -9 ping beenden.

Das ist ja wohl eher nicht der Sinn des Beispiels, aber ich bekomme es einfach nicht hin. Vielleicht findet ihr den Fehler?

Ich benutze Python2.3 unter Debian Sarge, ist da vielleicht thread-mode oder sowas nicht einkompiliert??

Hier mal das Programm (die erste IP im Bereich ist momentan Google, sollte also funktionieren):

import os
import re
import time
import sys
from threading import Thread

class testit(Thread):
def __init__ (self,ip):
Thread.__init__(self)
self.ip = ip
self.status = -1
def run(self):
pingaling = os.popen("ping -q -c2 "+self.ip,"r")
while 1:
line = pingaling.readline()
if not line: break
igot = re.findall(lifeline,line)
if igot:
self.status = int(igot[0])

lifeline = re.compile(r"(\d) received")
report = ("No response","Partial Response","Alive")

print time.ctime()

pinglist = []

for host in range(104,160):
ip = "66.249.93."+str(host)
current = testit(ip)
pinglist.append(current)
current.start()

for pingle in pinglist:
pingle.join()
print "Status from ",pingle.ip,"is",report[pingle.status]

print time.ctime()

RapidMax
12-10-2005, 18:24
Vermutlich hinterlässt popen den ping-Prozess als Zombi und der Thread bleibt am leben. Versuche mal was einfaches ohne dass ein Prozess erzeugt wird (diese aufgabe könntest du auch ohne Thread lösen, mit waitpid).

Gruss, Andy

TheGrudge
12-10-2005, 21:54
wenn ich top aufrufe, dann sind die pings aber nicht als zombies markiert.
Schade ich könnte das gut für die Arbeit gebrauchen, da schreibe ich eine Netzüberwachung in Perl, die mit Cacti und diversen Tools den Überblick über unser Netzwerk weltweit überwacht und sowas wie Ausfall von Routern, ISDN-Leitungen usw meldet.
Aber manche Sachen gehen viel einfacher in Python und deshalb wollte ich das mal lernen, vor allem die OOP-Fähigkeit und Threads sind hier schöner gelöst.
Naja vielleicht finde ich noch den Fehler...

fs111
16-10-2005, 19:40
Hast Du mal "os.wait()" am Ende des Codes versucht. das hat bei mir letztens auch ein Problem mit popen gelöst.

fs111

RapidMax
18-10-2005, 20:54
Ich habe erwähnt, dass es auch ohne Threas geht. Hier ein Beispiel, wie das aussehen könnte.

import os, sys
hosts = map(lambda x: "192.168.1.%d" % x, range(1, 254))
pidlist = {}

for host in hosts:
pid = os.fork()
if pid < 0:
os._exit(-1)
elif pid == 0:
si = file('/dev/null', 'r')
so = file('/dev/null', 'a+')
se = file('/dev/null', 'a+', 0)
os.dup2(si.fileno(), sys.stdin.fileno())
os.dup2(so.fileno(), sys.stdout.fileno())
os.dup2(se.fileno(), sys.stderr.fileno())
os.execl("/bin/ping", "/bin/ping", "-c", "3", host)
else:
pidlist[pid] = [ host ]

finished = 0
while finished < len(pidlist):
pid, status = os.waitpid(-1, 0)
pidlist[pid].append(status == 0)
finished += 1

for pid, status in pidlist.iteritems():
print pid, status

Und nun kannst du natürlich das auf den Thread zurückportieren, in jedem Thread mit os.wait() auf den Prozess warten, wie das fs111 erklärt hat. Nur bringen dir da die Threats herzlich wenig, ausser dass du gelernt hast, wie man sie nutzt.

Gruss, Andy