Threads in PyGTK: keep typing while ping-ing
bieffe62 at gmail.com
bieffe62 at gmail.com
Mon Feb 16 11:56:08 EST 2009
On 16 Feb, 14:47, Mamahita Sela <mamahitas... at yahoo.com> wrote:
> Dear All,
>
> I have read several howtos for threading in PyGTK. I have tried some but with no luck.
>
> What i want is: i can keep typing in gtk.TextView while periodically doing ping some hosts.
>
> I think, the thread part is working since i can ping so fast (even for not reply host, around 3 s for 27 no-reply-host). But, when the ping action is running, i can not typing in textview. What i type while pinging will show up after ping action is done.
>
> (I am using 2.5.1, pygtk 2.10.6 on Linux x86)
>
> This is my code:
> import threading
> import commands
> import gtk
> import gobject
>
> gtk.gdk.threads_init()
>
> class PingHost(threading.Thread):
> def __init__(self, host):
> threading.Thread.__init__(self)
> self.host = host
> self.result = ()
> def run(self):
> self.result = self.host, commands.getstatusoutput('ping %s -c1' %(self.host))[0]
>
> class Main:
> def __init__(self):
> self.win = gtk.Window()
> self.win.connect('destroy', gtk.main_quit)
> #
> self.textb = gtk.TextBuffer()
> self.textv = gtk.TextView(self.textb)
> self.textv.set_size_request(500, 500)
> #
> self.win.add(self.textv)
> self.win.show_all()
> #
> gobject.timeout_add(5000, self.do_ping)
>
> def do_ping(self):
> all_threads = []
> #
> for h in range(100, 105):
> host = '192.168.0.%d' %(h)
> #
> worker = PingHost(host)
> worker.start()
> all_threads.append(worker)
> #
> for t in all_threads:
> t.join()
> print t.result
> #
> return True
>
> if __name__ == '__main__':
> app = Main()
> gtk.main()
>
> Any help would be appreciated :)
> Best regards,
> M
As you have been already told, join() blocks until the thread is
terminated. and you should avoid that.
A simple fix could by add a timeout to t.join, doing something like :
t.join(JOIN_TIMEOUT);
if not t.isAlive():
print t.result
Anywway, starting a thread for each ping is not very efficient, so you
could do better by having a 'ping server thread'
that repeatedly performs the following steps:
- accepts ping command on a queue.Queue
- ping the target and waits for the result
- publish the result on another queue.Queue
At this point, the do_ping action should:
- send a ping command to the oping server
- check (in non blocking mode) if there is any result on the ping
results queue
- display the result, if any
Another big speedup would be to avoid spawning a subprocess fro each
ping and instead
using directly sockets to send ICMP packets, using recipes like this :
http://code.activestate.com/recipes/409689/
Ciao
------
FB
More information about the Python-list
mailing list