Description
Documentation
Hi.
It's not clear from the documentation that calling multiprocessing.get_context()
(with method=None
) has the side effect of also setting the default context globally, preventing future usage of multiprocessing.set_start_method()
.
import multiprocessing
default_context = multiprocessing.get_context() # "Fork" on Linux.
multiprocessing.set_start_method("spawn") # Error.
Which causes:
Traceback (most recent call last):
File "/home/delgan/test.py", line 5, in <module>
multiprocessing.set_start_method("spawn") # Error raised.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.11/multiprocessing/context.py", line 247, in set_start_method
raise RuntimeError('context has already been set')
RuntimeError: context has already been set
This is a surprising behavior because calling multiprocessing.get_context("fork")
then multiprocessing.set_start_method("spawn")
works perfectly fine. I assumed calling get_context(method=None)
would just create a context using the default method ("fork"
on Linux, "spawn"
otherwise) but there is visibly more to it than that.
I have a library allowing user to specify the multiprocessing.Context
of their choice:
def function(context=None):
if context is None:
context = multiprocessing.get_context()
pipe = context.Pipe()
...
This recipe looks correct, but it is not. It will cause a RuntimeError
if the user or another third-party library tries to call multiprocesing.set_start_method()
after using my function.
I'll probably need to refactor it to something like that:
def function(context=None):
if context is None:
start_method = multiprocessing.get_start_method(allow_none=True)
if start_method is not None:
context = multiprocessing.get_context(start_method)
elif os.name == "posix":
context = multiprocessing.get_context("fork")
else:
context = multiprocessing.get_context("spawn")
pipe = context.Pipe()
...
I wonder if there shouldn't be a method to retrieve the current context without setting one if there is none?
I would like to be able to use a Context
just like if I was using multiprocessing
directly.
Linked PRs
Metadata
Metadata
Assignees
Projects
Status