Strange threading behaviour
Rotwang
sg552 at hotmail.co.uk
Thu Jun 21 14:03:37 EDT 2012
On 21/06/2012 18:07, Dave Angel wrote:
> On 06/21/2012 11:19 AM, Rotwang wrote:
>> 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?
>>
>>
>
> I did not study your code, as I'm not very familiar with tkinter.
> However, I think I know your problem:
>
> You do not want to try to start up threads from within a import. An
> import is special, and somehow blocks threading while it's running.
That would explain it.
> Consequently, a module should not try to do anything too fancy from
> within its top-level code. Add in the traditional:
>
> def main():
> m = myclass()
> m.gui()
>
> if __name__ == "__main__":
> main()
>
> and just run it from the command line, as python bugtest.py
In fact, running the module directly from the command line makes it work
properly as-is.
Thanks for your post.
--
Hate music? Then you'll hate this:
http://tinyurl.com/psymix
More information about the Python-list
mailing list