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
Documentation
Hi.
It's not clear from the documentation that calling
multiprocessing.get_context()(withmethod=None) has the side effect of also setting the default context globally, preventing future usage ofmultiprocessing.set_start_method().Which causes:
This is a surprising behavior because calling
multiprocessing.get_context("fork")thenmultiprocessing.set_start_method("spawn")works perfectly fine. I assumed callingget_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.Contextof their choice:This recipe looks correct, but it is not. It will cause a
RuntimeErrorif the user or another third-party library tries to callmultiprocesing.set_start_method()after using my function.I'll probably need to refactor it to something like that:
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
Contextjust like if I was usingmultiprocessingdirectly.Linked PRs
multiprocessing.get_context()sets the global context #109488