Rotwang <sg...@hotmail.co.uk> writes: > Hi all, I'm using Python 2.7.2 on Windows 7 and a module I've written > is acting strangely. I can reproduce the behaviour in question with > the following: > > --- begin bugtest.py --- > > import threading, Tkinter, os, pickle > > class savethread(threading.Thread): > def __init__(self, value): > threading.Thread.__init__(self) > self.value = value > def run(self): > print 'Saving:', > with open(os.path.join(os.getcwd(), 'bugfile'), 'wb') as f: > pickle.dump(self.value, f) > print 'saved' > > class myclass(object): > def gui(self): > root = Tkinter.Tk() > root.grid() > def save(event): > savethread(self).start() > root.bind('s', save) > root.wait_window() > > m = myclass() > m.gui() > > --- end bugtest.py --- > > > Here's the problem: suppose I fire up Python and type > >>>> import bugtest > > and then click on the Tk window that spawns and press 's'. Then > 'Saving:' gets printed, and an empty file named 'bugfile' appears in > my current working directory. But nothing else happens until I close > the Tk window; as soon as I do so the file is written to and 'saved' > gets printed. If I subsequently type > >>>> bugtest.m.gui() > > and then click on the resulting window and press 's', then 'Saving: > saved' gets printed and the file is written to immediately, exactly as > I would expect. Similarly if I remove the call to m.gui from the > module and just call it myself after importing then it all works > fine. But it seems as if calling the gui within the module itself > somehow stops savethread(self).run from finishing its job while the > gui is still alive. > > Can anyone help?
It looks as if some waiting operation in the "wait_window" call did not release the GIL (the "Global Interpreter Lock" which ensures that at most one Python thread can run at a given time and protects the Python data structures such as the reference counts and interpreter state). In this case, you could expect some non-deterministic behaviour. If your thread is fast enough to finish before the internal activity inside "wait_window" gets the GIL again, everything completes immediately; otherwise, things complete only after the internal waiting ends and Python code is again executed. It might well be possible that "TKinter" has not been designed for a multi threaded environment; alternatively, there might be a bug. If "TKinter" truely supports multithreaded applications, any call to "tk" would need to release the GIL and any callback into Python reacquire it. Strange things of the kind you observe could happen when this is forgotten at a single place. -- http://mail.python.org/mailman/listinfo/python-list