[pygtk] Threading

Antoon Pardon Antoon.Pardon at rece.vub.ac.be
Thu Jun 24 15:22:55 WST 2004


On Wed, Jun 23, 2004 at 07:52:38AM -0400, dave wrote:
> This is some of the code I use...it may not be perfect, but it does work 
> reliably on win32 and linux.
> 
> -dave
> 
>    def handle_gui_queue(self,command,args):
>        """
>        Callback the gui_queue uses whenever it recieves a command for us.
>        command is a string
>        args is a list of arguments for the command
>        """
>       
>        #print "handle_gui_queue"
>        if command=="set_label":
>            #print "setting label"
>            obj=args[0]
>            label=args[1]
>            obj.set_label(label)
>        elif command=="do_listener_shell":
>            lst=args[0]
>            #print "doing a listener shell"
>            self.do_listener_shell(listener=lst)
> 
> #gui_queue.py
> class gui_queue:
>    """wakes up the gui thread which then clears our queue"""
>    def __init__(self,gui,listenport=0):
>        """If listenport is 0, we create a random port to listen on"""
>        self.mylock=RLock()
>        self.myqueue=[]
>        if listenport==0:
>            self.listenport=random.randint(1025,10000)
>        else:
>            self.listenport=listenport
>        print "Local GUI Queue listening on port %s"%self.listenport
>        s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
>        s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
>        s.bind(("", self.listenport)) 
>        self.listensocket=s
>        self.listensocket.listen(300) #listen for activity.
>        #time.sleep(15)
>        self.gui=gui
>        return
>   
>    def append(self,command,args):
>        """
>        Append can be called by any thread
>        """
>        self.mylock.acquire()
>        self.myqueue.append((command,args))
>        #this won't work on a host with a ZoneAlarm firewall or no 
> internet connectivity...
>        s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
>        #small timeout will wake up the gui thread, but not
>        #cause painful pauses if we are already in the gui thread.
>        #important to note that we use timeoutsocket and it
>        #is already loaded.
>        s.set_timeout(0.01)
>        #wakey wakey!
>        #print "Connecting to port %d"%self.listenport
>        try:
>            s=s.connect(("localhost",self.listenport))
>        except:
>            #ignore timeouts
>            pass
>        self.mylock.release()
>        return
> 
>    def clearqueue(self):
>        """
>        Clearqueue is only called by the main GUI thread
>        Don't forget to return 1
>        """
>        #print "Clearing queue"
>        #clear this...TODO: add select call here.
>        newconn,addr=self.listensocket.accept()
>        for i in self.myqueue:
>            (command,args)=i
>            self.gui.handle_gui_queue(command,args)
>        self.myqueue=[]
>        return 1
> 

I think your code runs the risk of being overrun.
If your background tasks append commands faster
than the main thread can handle them, the main
thread can be stuck in the clearqueue an arbitrary
long time, making your application unresponsive.

-- 
Antoon Pardon


More information about the pygtk mailing list