odd runtime error

David Brown dmlb2000 at gmail.com
Wed Dec 1 20:27:05 EST 2010


On Wed, Dec 1, 2010 at 5:19 PM, Cameron Simpson <cs at zip.com.au> wrote:
> On 01Dec2010 16:49, David Brown <dmlb2000 at gmail.com> wrote:
> | So I'm not subscribed to python-list but would like to get an answer
> | to my question. I've made a small test program that dumps a
> | RuntimeError and I'd like to know why.
> |
> | $ python test2.py
> | doing stuff
> | Traceback (most recent call last):
> |   File "test2.py", line 3, in <module>
> |     import test
> | RuntimeError: not holding the import lock
> | child 3693 exited with 256
> | $
> |
> | Here's the setup, there's two files test.py and test2.py
> |
> | $ cat test.py
> | #!/usr/bin/python
> |
> | import os, sys
> |
> | if os.fork() == 0:
> |       print "doing stuff"
> |       sys.exit()
> |
> | print "child %d exited with %d" % os.wait()
> | $ cat test2.py
> | #!/usr/bin/python
> |
> | import test
> | $
> |
> | I understand that sys.exit() is really just doing a `raise
> | SystemExit(0)' and the RuntimeError shows up with that as well. If you
> | change out sys.exit with os._exit(0) then it doesn't show dump the
> | RuntimeError. Also, this seems to be a python2.6 and python2.7 issue.
> | Python3 doesn't have this issue. I haven't checked with python2.5 or
> | before yet.
> |
> | I was more curious about what this behavior is and why python is doing
> | things this way. I've scoured the python documentation and can't seem
> | to figure out why.
>
> So, test2.py imports "test", which is in "test.py".
> And the test module forks _during_ the import.
>
> Python takes a lock during imports - this stops multiple threads
> from importing the same module at the same time (avoiding multiple
> instantiation etc) and other racy fribbing with the in-memory module
> data structures.
>
> So:
>  import test
>    test.py...
>      fork...
>
> At this point two programs exist, each in the midst of the import of
> test.py. It would seem the import lock breaks over the fork, so that the
> child process doesn't hold the lock. But because it is a fork, it does
> not know this! (Being identical to its parent.) So you raise SystemExit,
> and during the stack unwind the child tries to release the lock. Which
> it doesn't have, thus the breakage.
>
> Does that clarify the sequence of events?

Thanks for the clarification I like the idea of wrapping all the
primary code in the script to a main function then calling it if its
being called by main. I think I got a better handle on things.

Thanks,
- David Brown

> Cameron Simpson <cs at zip.com.au> DoD#743
> http://www.cskk.ezoshosting.com/cs/
>
> "I think not," said Descartes, and promptly disappeared.
>



More information about the Python-list mailing list