Closed
Description
Consider the following bug:
trio.to_thread.run_sync()
is called, creating a worker thread. The worker thread is left in the globalTHREAD_CACHE
.- The Python process forks for some reason (perhaps via the
multiprocessing
module) - The child process now calls
trio.to_thread.run_sync()
. The globalTHREAD_CACHE
still contains a reference to the worker thread, so the child process thinks it has an idle worker thread, and tries to dispatch a task to it. However, the worker thread doesn't actually exist in the child process. Sotrio.to_thread.run_sync()
hangs forever.
Because THREAD_CACHE
is interpreter-global, this can happen even if the two Trio run loop are completely separate. For example, in a test suite, one test might call trio.to_thread.run_sync()
, and then later a completely separate test might use multiprocessing
to spawn a process that calls trio.to_thread.run_sync()
.
I think it should be fairly simple to fix this by using os.register_at_fork()
to ensure THREAD_CACHE
is cleared in the child whenever the interpreter forks.
Metadata
Metadata
Assignees
Labels
No labels