New submission from roudkerk:
I got a report that one of the tests for processing
(http://cheeseshop.python.org/pypi/processing) was failing with
Fatal Python error: Invalid thread state for this thread
when run with a debug interpreter. This appears to be caused by the
interaction between os.fork() and threads. The following attached
program reliably reproduces the problem for me on Ubuntu edgy for x86.
All that happens is that the parent process starts a subthread then
forks, and then the child process starts a subthread.
With the normal interpreter I get
started thread -1211028576 in process 18683
I am thread -1211028576 in process 18683
started thread -1211028576 in process 18685
I am thread -1211028576 in process 18685
as expected, but with the debug interpreter I get
started thread -1210782816 in process 18687
I am thread -1210782816 in process 18687
started thread -1210782816 in process 18689
Fatal Python error: Invalid thread state for this thread
[5817 refs]
Notice that the child process is reusing a thread id that was
being used by the parent process at the time of the fork.
The code raising the error seems to be in pystate.c:
PyThreadState *
PyThreadState_Swap(PyThreadState *new)
{
PyThreadState *old = _PyThreadState_Current;
_PyThreadState_Current = new;
/* It should not be possible for more than one thread state
to be used for a thread. Check this the best we can in
debug
builds.
*/
#if defined(Py_DEBUG) && defined(WITH_THREAD)
if (new) {
PyThreadState *check = PyGILState_GetThisThreadState();
if (check && check != new)
Py_FatalError("Invalid thread state for this
thread");
}
#endif
return old;
}
It looks as though PyGILState_GetThisThreadState() is returning the
thread state of the thread from the parent process which has the same
id as the current thread. Therefore the check fails.
I think the thread local storage implementation in thread.c should
provide a function _PyThread_ReInitTLS() which PyOS_AfterFork() can
call. I think _PyThread_ReInitTLS() just needs to remove and free
each "struct key" in the linked list which does not match the id of
the calling thread.
----------
components: Interpreter Core
files: dbg2.py
messages: 58954
nosy: roudkerk
severity: normal
status: open
title: Thread local storage and PyGILState_* mucked up by os.fork()
type: crash
versions: Python 2.4, Python 2.5
Added file: http://bugs.python.org/file9023/dbg2.py
__________________________________
Tracker <[EMAIL PROTECTED]>
<http://bugs.python.org/issue1683>
__________________________________
import time, os, thread
def f():
print "I am thread %d in process %d" % (thread.get_ident(),os.getpid())
time.sleep(1)
ident = thread.start_new_thread(f, ())
print "started thread %d in process %d" % (ident, os.getpid())
time.sleep(0.5) # give thread a chance to start
pid = os.fork()
if pid == 0:
ident = thread.start_new_thread(f, ())
print "started thread %d in process %d" % (ident, os.getpid())
time.sleep(0.5) # give thread a chance to start
os._exit(0)
os.waitpid(pid, 0)
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com