odd runtime error

Cameron Simpson cs at zip.com.au
Wed Dec 1 20:19:05 EST 2010


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?
-- 
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