Message195891
When a thread is started in CPython, t_bootstrap [Modules/threadmodule.c] creates a PyThreadState object and then calls Thread.__bootstrap_inner [Lib/threading.py] which calls Thread.run, protected with self.__block, a Condition. Thread.join uses the same __block to block until Thread.run finished.
When Thread.run finished, __bootstrap_inner notifies on __block, so join will return. Here lies a race condition, if a thread switch to Thread.join occures before __bootstrap_inner returns to t_bootstrap. Then join will return before the PyThreadState for the thread is destroyed by t_bootstrap.
It is mostly harmless for general use, as __bootstrap_inner eventually gets scheduled again and PyThreadState is taken care of.
However. Py_EndInterpreter [Python/pythonrun.c] can be called when only the main interpreter thread is running. So when we want to call Py_EndInterpreter, we signal every other thread to stop, and join them. And when Thread.join returns, we call Py_EndInterpreter. Py_EndInterpreter checks if there are any other PyThreadStates still around and does a Py_FatalError.
As a workaround, we now do a sleep after join. |
|
Date |
User |
Action |
Args |
2013-08-22 13:56:37 | Tamas.K | set | recipients:
+ Tamas.K |
2013-08-22 13:56:37 | Tamas.K | set | messageid: <1377179797.68.0.40345735309.issue18808@psf.upfronthosting.co.za> |
2013-08-22 13:56:37 | Tamas.K | link | issue18808 messages |
2013-08-22 13:56:37 | Tamas.K | create | |
|