Skip to content

Commit b1694cf

Browse files
committed
Issue #18999: Make multiprocessing use context objects.
This allows different parts of a program to use different methods for starting processes without interfering with each other.
1 parent 3e4b528 commit b1694cf

20 files changed

+736
-614
lines changed

Doc/library/multiprocessing.rst

+65-11
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,8 @@ necessary, see :ref:`multiprocessing-programming`.
9898

9999

100100

101-
Start methods
102-
~~~~~~~~~~~~~
101+
Contexts and start methods
102+
~~~~~~~~~~~~~~~~~~~~~~~~~~
103103

104104
Depending on the platform, :mod:`multiprocessing` supports three ways
105105
to start a process. These *start methods* are
@@ -132,7 +132,7 @@ to start a process. These *start methods* are
132132
unnecessary resources are inherited.
133133

134134
Available on Unix platforms which support passing file descriptors
135-
over unix pipes.
135+
over Unix pipes.
136136

137137
Before Python 3.4 *fork* was the only option available on Unix. Also,
138138
prior to Python 3.4, child processes would inherit all the parents
@@ -153,18 +153,46 @@ example::
153153

154154
import multiprocessing as mp
155155

156-
def foo():
157-
print('hello')
156+
def foo(q):
157+
q.put('hello')
158158

159159
if __name__ == '__main__':
160160
mp.set_start_method('spawn')
161-
p = mp.Process(target=foo)
161+
q = mp.Queue()
162+
p = mp.Process(target=foo, args=(q,))
162163
p.start()
164+
print(q.get())
163165
p.join()
164166

165167
:func:`set_start_method` should not be used more than once in the
166168
program.
167169

170+
Alternatively, you can use :func:`get_context` to obtain a context
171+
object. Context objects have the same API as the multiprocessing
172+
module, and allow one to use multiple start methods in the same
173+
program. ::
174+
175+
import multiprocessing as mp
176+
177+
def foo(q):
178+
q.put('hello')
179+
180+
if __name__ == '__main__':
181+
ctx = mp.get_context('spawn')
182+
q = ctx.Queue()
183+
p = ctx.Process(target=foo, args=(q,))
184+
p.start()
185+
print(q.get())
186+
p.join()
187+
188+
Note that objects related to one context may not be compatible with
189+
processes for a different context. In particular, locks created using
190+
the *fork* context cannot be passed to a processes started using the
191+
*spawn* or *forkserver* start methods.
192+
193+
A library which wants to use a particular start method should probably
194+
use :func:`get_context` to avoid interfering with the choice of the
195+
library user.
168196

169197

170198
Exchanging objects between processes
@@ -859,11 +887,30 @@ Miscellaneous
859887

860888
.. versionadded:: 3.4
861889

862-
.. function:: get_start_method()
890+
.. function:: get_context(method=None)
891+
892+
Return a context object which has the same attributes as the
893+
:mod:`multiprocessing` module.
863894

864-
Return the current start method. This can be ``'fork'``,
865-
``'spawn'`` or ``'forkserver'``. ``'fork'`` is the default on
866-
Unix, while ``'spawn'`` is the default on Windows.
895+
If *method* is *None* then the default context is returned.
896+
Otherwise *method* should be ``'fork'``, ``'spawn'``,
897+
``'forkserver'``. :exc:`ValueError` is raised if the specified
898+
start method is not available.
899+
900+
.. versionadded:: 3.4
901+
902+
.. function:: get_start_method(allow_none=False)
903+
904+
Return the name of start method used for starting processes.
905+
906+
If the start method has not been fixed and *allow_none* is false,
907+
then the start method is fixed to the default and the name is
908+
returned. If the start method has not been fixed and *allow_none*
909+
is true then *None* is returned.
910+
911+
The return value can be ``'fork'``, ``'spawn'``, ``'forkserver'``
912+
or *None*. ``'fork'`` is the default on Unix, while ``'spawn'`` is
913+
the default on Windows.
867914

868915
.. versionadded:: 3.4
869916

@@ -1785,7 +1832,7 @@ Process Pools
17851832
One can create a pool of processes which will carry out tasks submitted to it
17861833
with the :class:`Pool` class.
17871834

1788-
.. class:: Pool([processes[, initializer[, initargs[, maxtasksperchild]]]])
1835+
.. class:: Pool([processes[, initializer[, initargs[, maxtasksperchild [, context]]]]])
17891836

17901837
A process pool object which controls a pool of worker processes to which jobs
17911838
can be submitted. It supports asynchronous results with timeouts and
@@ -1805,6 +1852,13 @@ with the :class:`Pool` class.
18051852
unused resources to be freed. The default *maxtasksperchild* is None, which
18061853
means worker processes will live as long as the pool.
18071854

1855+
.. versionadded:: 3.4
1856+
*context* can be used to specify the context used for starting
1857+
the worker processes. Usually a pool is created using the
1858+
function :func:`multiprocessing.Pool` or the :meth:`Pool` method
1859+
of a context object. In both cases *context* is set
1860+
appropriately.
1861+
18081862
.. note::
18091863

18101864
Worker processes within a :class:`Pool` typically live for the complete

0 commit comments

Comments
 (0)