-
-
Notifications
You must be signed in to change notification settings - Fork 33.1k
Description
Bug report
Bug description:
Trying to create a mutliprocessing.Pool
in a sub-interpreter fails due to the use of daemon threads.
How I ran into it: as an experiment, I was trying to run pytest in a sub-interpreter (on its own test suite). One of the tests is using multiprocessing.Pool
and fails. (There are other failures, particularly faulthandler
and readline
incompatibilities, but those are unrelated to this issue).
If mutliprocessing.Pool
and concurrent.interpreters
are fundamentally incompatible for some reason, perhaps it can be documented.
from concurrent import interpreters
interp = interpreters.create()
interp.exec("""
import multiprocessing
pool = multiprocessing.Pool()
""")
Traceback:
Traceback (most recent call last):
File "x.py", line 5, in <module>
interp.exec("""
~~~~~~~~~~~^^^^
import multiprocessing
^^^^^^^^^^^^^^^^^^^^^^
pool = multiprocessing.Pool()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
""")
^^^^
File "/home/ran/.local/share/uv/python/cpython-3.14.0-linux-x86_64-gnu/lib/python3.14/concurrent/interpreters/__init__.py", line 212, in exec
raise ExecutionFailed(excinfo)
concurrent.interpreters.ExecutionFailed: RuntimeError: daemon threads are disabled in this interpreter
Uncaught in the interpreter:
Traceback (most recent call last):
File "<script>", line 3, in <module>
File "/home/ran/.local/share/uv/python/cpython-3.14.0-linux-x86_64-gnu/lib/python3.14/multiprocessing/context.py", line 119, in Pool
return Pool(processes, initializer, initargs, maxtasksperchild,
context=self.get_context())
File "/home/ran/.local/share/uv/python/cpython-3.14.0-linux-x86_64-gnu/lib/python3.14/multiprocessing/pool.py", line 233, in __init__
self._worker_handler.daemon = True
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/ran/.local/share/uv/python/cpython-3.14.0-linux-x86_64-gnu/lib/python3.14/threading.py", line 1207, in daemon
raise RuntimeError('daemon threads are disabled in this interpreter')
RuntimeError: daemon threads are disabled in this interpreter
Link to relevant code:
cpython/Lib/multiprocessing/pool.py
Lines 226 to 253 in 6481539
self._worker_handler = threading.Thread( | |
target=Pool._handle_workers, | |
args=(self._cache, self._taskqueue, self._ctx, self.Process, | |
self._processes, self._pool, self._inqueue, self._outqueue, | |
self._initializer, self._initargs, self._maxtasksperchild, | |
self._wrap_exception, sentinels, self._change_notifier) | |
) | |
self._worker_handler.daemon = True | |
self._worker_handler._state = RUN | |
self._worker_handler.start() | |
self._task_handler = threading.Thread( | |
target=Pool._handle_tasks, | |
args=(self._taskqueue, self._quick_put, self._outqueue, | |
self._pool, self._cache) | |
) | |
self._task_handler.daemon = True | |
self._task_handler._state = RUN | |
self._task_handler.start() | |
self._result_handler = threading.Thread( | |
target=Pool._handle_results, | |
args=(self._outqueue, self._quick_get, self._cache) | |
) | |
self._result_handler.daemon = True | |
self._result_handler._state = RUN | |
self._result_handler.start() |
I'd also note that multiprocessing.Queue
uses daemon thread:
cpython/Lib/multiprocessing/queues.py
Lines 178 to 186 in 6481539
self._thread = threading.Thread( | |
target=Queue._feed, | |
args=(self._buffer, self._notempty, self._send_bytes, | |
self._wlock, self._reader.close, self._writer.close, | |
self._ignore_epipe, self._on_queue_feeder_error, | |
self._sem), | |
name='QueueFeederThread', | |
daemon=True, | |
) |
CPython versions tested on:
3.14
Operating systems tested on:
Linux
Linked PRs
Metadata
Metadata
Assignees
Labels
Projects
Status