Message195891
| Author |
Tamas.K |
| Recipients |
Tamas.K |
| Date |
2013年08月22日.13:56:37 |
| SpamBayes Score |
-1.0 |
| Marked as misclassified |
Yes |
| Message-id |
<1377179797.68.0.40345735309.issue18808@psf.upfronthosting.co.za> |
| In-reply-to |
| Content |
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. |
|
History
|
|---|
| 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 |
|