Using a Queue

As an alternative I'll try using a Queue. The idea is that in order to avoid the complexities of multiple threads making gdk call that can interfere, we have a seperate thread that makes all the gdk calls and the other threads direct the needed information through a queue.

The drawing thread then looks something like the following:

    def Drawing():
        while 1:
	    Id, ShowTime, ShowValue = Queue.get()
	    gdk.threads_enter()
            canvas.Adjust(Id, ShowTime , ShowValue)
            gdk.threads_leave()

The working threads then become something like the following. (A full demo implementing this idea can be found in demo2.py.)

    class Counting (Thread):
    
        def __init__(self, Id)
    
        def run(self):
            while ...:
                Calculate Results 
                Queue.put((self.Id, self.ShowTime , self.ShowValue))

        def Start_Stop(self,ignore)
    
        def Modus(self,ignore):
            if Running:
                Change Mode
            else:
                Reset Values
                gdk.threads_leave()
                Queue.put((self.Id, self.ShowTime , self.ShowValue))
	        gdk.threads_enter()
		
        def Quit(self):
            Make thread leave loop

And we notice we have the same kind of problem as with the previous solution but in a reversed form. The reason for the gdk lock in reverse around the Queue.put() in the Modus method is again the fact that a signal handler is implicitly imbedded in a gdk lock pair. So without the gdk lock calls in the Modus method we could have the following situation: Threads fill up the queue, user clicks a button, gtk.gdk_threads_enter is implicitly called before Modus is entered. In the mean time Drawing tries to call gtk.gdk_threads_enter and blocks, Modus want to put the values on the Queue but that is full so the main thread blocks too: Deadlock.

Of course we could use an unlimited queue and that might work in a lot of cases, but it doesn't work in this case. The problem is that the working threads together produce results faster than the drawing thread can process them. So with an unlimited queue, the queue will just grow and the whole program will act sluggish and erratic.

PREV NEXT