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