Threads and import

Rhamphoryncus rhamph at gmail.com
Thu May 29 13:25:06 EDT 2008


On May 28, 1:14 pm, rsoh.woodho... at googlemail.com wrote:
> Hi,
>
> I'm trying to work out some strange (to me) behaviour that I see when
> running a python script in two different ways (I've inherited some
> code that needs to be maintained and integrated with another lump of
> code). The sample script is:
>
> # Sample script, simply create a new thread and run a
> # regular expression match in it.
> import re
>
> import threading
> class TestThread(threading.Thread):
>
>     def run(self):
>         print('start')
>         try:
>             re.search('mmm', 'mmmm')
>         except Exception, e:
>             print e
>         print('finish')
>
> tmpThread = TestThread()
> tmpThread.start()
> tmpThread.join()
> import time
> for i in range(10):
>     time.sleep(0.5)
>     print i
>
> # end of sample script
>
> Now if I run this using:
>
> $ python ThreadTest.py
>
> then it behaves as expected, ie an output like:
>
> start
> finish
> 0
> 1
> 2
> ...
>
> But if I run it as follows (how the inherited code was started):
>
> $ python -c "import TestThread"
>
> then I just get:
>
> start
>
> I know how to get around the problem but could someone with more
> knowledge of how python works explain why this is the case?

For reasons I haven't figured out, child threads always acquire the
import lock.  Since the main thread is already in an import, and is
waiting for the child thread to finish, this deadlocks.

"python ThreadTest.py" doesn't deadlock because ThreadTest isn't
loaded as a module - it's loaded as a script.  A script doesn't hold
the import lock while it executes.

The solution is to move all the thread spawning and whatnot into a
main() function, use the "if __name__ == '__main__': main()" trick for
when you are a script, and if a module require the caller to do
ThreadTest.main() after importing.



More information about the Python-list mailing list