[Tutor] thread locks

dman dsh8290@rit.edu
Tue, 4 Dec 2001 15:55:25 -0500


On Mon, Dec 03, 2001 at 11:41:02PM -0500, Rick Pasotto wrote:
| On Mon, Dec 03, 2001 at 08:28:28PM -0500, dman wrote:
| > On Mon, Dec 03, 2001 at 04:39:38PM -0500, Rick Pasotto wrote:
| > 
| > | Or is there a better way to solve my problem?
| > 
| > import threading , time
| > def func() :
| >     while 1 : pass # do something that takes a while
| > 
| > t = threading.Thread( target=func )
| > t.start()
| > while t.isAlive() : time.sleep( 1 )
| 
| This works with one addition:
| 
| while t.isAlive() :
| 	self.win.update()
|     time.sleep( 1 )
| 
| > | I know this seems to defeat the purpose of using a thread but this is
| > | in a Tkinter program and if I don't do this the main window will not
| > | get redrawn if the user covers it up, etc.
| > 
| > Depending on how this is used and what it affects, you could just
| > start the thread and let it go.  Sometimes there is no need to make
| > the user wait until it is done.
| 
| Until the process is done (the info is retrieved) there is nothing for
| the user to do.

They can look at the window :-).  Ideally you would have some sort of
animation to show that the program is still working.  This is more
important on a windows system where things have a greater tendency to
stop working.

| > BTW, you are aware that Tk is not thread-safe, right?  It is only safe
| > to modify any widgets in the Tk main thread.
| 
| Which is why I asked the question. The long running process is in a
| class that has no need to know that it's being run from a gui so I don't
| want to put any gui stuff in it yet I need to update the gui while it's
| running. By putting it in a thread I can stay in the main program to
| update the gui and then proceed when the thread finishes.

So just start the thread and forget about it.  Your event handler can
return (in the even thread) and allow Tk's mainloop to continue.  The
worker thread will keep working independently of that.

| This is working fine for me. I've got a widget with an after() method
| that continuously checks a global variable that is written to (within
| a lock) by the thread. The thread itself doesn't make any actual gui
| calls, it just appends to the global list variable.

This isn't ideal -- polling and a global variable.  It might help to
look at the 'threading' module -- it has some higher level concurrency
support than the 'thread' module.  In particular, the Event class
would be of interest to you.  You create an event.  The worker thread
will set() the event when it is done preparing the data.  In the mean
time that other widget wait()'s for the event to be set.  It is a
blocking call, which means that you don't do any polling.

It would be better to redesign the system so that the data is a local
variable that is passed around as necessary, but if it functions then
don't bother redesigning until you really need to redesign the system
(like when the current design can no longer meet the (ever changing)
needs of users).

HTH,
-D

-- 

(E)ighteen (M)egs (A)nd (C)onstantly (S)wapping