Skip to content

Commit 9da008d

Browse files
miss-islingtonYvesDupgpshead
authored
[3.14] gh-132898: Add a note in multiprocessing.Process docs about creating a process in a REPL (GH-137118) (#137154)
Co-authored-by: Duprat <yduprat@gmail.com> Co-authored-by: Gregory P. Smith <greg@krypto.org>
1 parent aeb55eb commit 9da008d

File tree

2 files changed

+53
-8
lines changed

2 files changed

+53
-8
lines changed

Doc/library/concurrent.futures.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,11 @@ that :class:`ProcessPoolExecutor` will not work in the interactive interpreter.
342342
Calling :class:`Executor` or :class:`Future` methods from a callable submitted
343343
to a :class:`ProcessPoolExecutor` will result in deadlock.
344344

345+
Note that the restrictions on functions and arguments needing to picklable as
346+
per :class:`multiprocessing.Process` apply when using :meth:`~Executor.submit`
347+
and :meth:`~Executor.map` on a :class:`ProcessPoolExecutor`. A function defined
348+
in a REPL or a lambda should not be expected to work.
349+
345350
.. class:: ProcessPoolExecutor(max_workers=None, mp_context=None, initializer=None, initargs=(), max_tasks_per_child=None)
346351

347352
An :class:`Executor` subclass that executes calls asynchronously using a pool

Doc/library/multiprocessing.rst

Lines changed: 48 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,10 @@ To show the individual process IDs involved, here is an expanded example::
9797
For an explanation of why the ``if __name__ == '__main__'`` part is
9898
necessary, see :ref:`multiprocessing-programming`.
9999

100+
The arguments to :class:`Process` usually need to be unpickleable from within
101+
the child process. If you tried typing the above example directly into a REPL it
102+
could lead to an :exc:`AttributeError` in the child process trying to locate the
103+
*f* function in the ``__main__`` module.
100104

101105

102106
.. _multiprocessing-start-methods:
@@ -233,9 +237,12 @@ processes for a different context. In particular, locks created using
233237
the *fork* context cannot be passed to processes started using the
234238
*spawn* or *forkserver* start methods.
235239

236-
A library which wants to use a particular start method should probably
237-
use :func:`get_context` to avoid interfering with the choice of the
238-
library user.
240+
Libraries using :mod:`multiprocessing` or
241+
:class:`~concurrent.futures.ProcessPoolExecutor` should be designed to allow
242+
their users to provide their own multiprocessing context. Using a specific
243+
context of your own within a library can lead to incompatibilities with the
244+
rest of the library user's application. Always document if your library
245+
requires a specific start method.
239246

240247
.. warning::
241248

@@ -538,9 +545,42 @@ The :mod:`multiprocessing` package mostly replicates the API of the
538545
to pass to *target*.
539546

540547
If a subclass overrides the constructor, it must make sure it invokes the
541-
base class constructor (:meth:`Process.__init__`) before doing anything else
548+
base class constructor (``super().__init__()``) before doing anything else
542549
to the process.
543550

551+
.. note::
552+
553+
In general, all arguments to :class:`Process` must be picklable. This is
554+
frequently observed when trying to create a :class:`Process` or use a
555+
:class:`concurrent.futures.ProcessPoolExecutor` from a REPL with a
556+
locally defined *target* function.
557+
558+
Passing a callable object defined in the current REPL session causes the
559+
child process to die via an uncaught :exc:`AttributeError` exception when
560+
starting as *target* must have been defined within an importable module
561+
in order to be loaded during unpickling.
562+
563+
Example of this uncatchable error from the child::
564+
565+
>>> import multiprocessing as mp
566+
>>> def knigit():
567+
... print("Ni!")
568+
...
569+
>>> process = mp.Process(target=knigit)
570+
>>> process.start()
571+
>>> Traceback (most recent call last):
572+
File ".../multiprocessing/spawn.py", line ..., in spawn_main
573+
File ".../multiprocessing/spawn.py", line ..., in _main
574+
AttributeError: module '__main__' has no attribute 'knigit'
575+
>>> process
576+
<SpawnProcess name='SpawnProcess-1' pid=379473 parent=378707 stopped exitcode=1>
577+
578+
See :ref:`multiprocessing-programming-spawn`. While this restriction is
579+
not true if using the ``"fork"`` start method, as of Python ``3.14`` that
580+
is no longer the default on any platform. See
581+
:ref:`multiprocessing-start-methods`.
582+
See also :gh:`132898`.
583+
544584
.. versionchanged:: 3.3
545585
Added the *daemon* parameter.
546586

@@ -3058,10 +3098,10 @@ start method.
30583098

30593099
More picklability
30603100

3061-
Ensure that all arguments to :meth:`Process.__init__` are picklable.
3062-
Also, if you subclass :class:`~multiprocessing.Process` then make sure that
3063-
instances will be picklable when the :meth:`Process.start
3064-
<multiprocessing.Process.start>` method is called.
3101+
Ensure that all arguments to :class:`~multiprocessing.Process` are
3102+
picklable. Also, if you subclass ``Process.__init__``, you must make sure
3103+
that instances will be picklable when the
3104+
:meth:`Process.start <multiprocessing.Process.start>` method is called.
30653105

30663106
Global variables
30673107

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy