mirror of
https://github.com/python/cpython.git
synced 2025-11-03 03:22:27 +00:00
Merged revisions 64407,64568 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk ........ r64407 | andrew.kuchling | 2008-06-19 14:48:42 -0500 (Thu, 19 Jun 2008) | 1 line Remove some standalone material from the introduction; various markup and typo fixes ........ r64568 | benjamin.peterson | 2008-06-27 18:22:06 -0500 (Fri, 27 Jun 2008) | 1 line edit multiprocessing docs ........
This commit is contained in:
parent
d5cd65b72c
commit
5289b2b1fe
1 changed files with 93 additions and 158 deletions
|
|
@ -4,81 +4,24 @@
|
||||||
.. module:: multiprocessing
|
.. module:: multiprocessing
|
||||||
:synopsis: Process-based "threading" interface.
|
:synopsis: Process-based "threading" interface.
|
||||||
|
|
||||||
:mod:`multiprocessing` is a package for the Python language which supports the
|
|
||||||
spawning of processes using a similar API of the :mod:`threading` module. It
|
|
||||||
runs on both Unix and Windows.
|
|
||||||
|
|
||||||
The :mod:`multiprocessing` module offers the capability of both local and remote
|
|
||||||
concurrency effectively side-stepping the Global Interpreter Lock by utilizing
|
|
||||||
subprocesses for "threads". Due to this, the :mod:`multiprocessing` module
|
|
||||||
allows the programmer to fully leverage multiple processors on a given machine.
|
|
||||||
|
|
||||||
|
|
||||||
Introduction
|
Introduction
|
||||||
------------
|
----------------------
|
||||||
|
|
||||||
|
:mod:`multiprocessing` is a package that supports spawning processes using an
|
||||||
Threads, processes and the GIL
|
API similar to the :mod:`threading` module. The :mod:`multiprocessing` package
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
offers both local and remote concurrency, effectively side-stepping the
|
||||||
|
:term:`Global Interpreter Lock` by using subprocesses instead of threads. Due
|
||||||
To run more than one piece of code at the same time on the same computer one has
|
to this, the :mod:`multiprocessing` module allows the programmer to fully
|
||||||
the choice of either using multiple processes or multiple threads.
|
leverage multiple processors on a given machine. It runs on both Unix and
|
||||||
|
Windows.
|
||||||
Although a program can be made up of multiple processes, these processes are in
|
|
||||||
effect completely independent of one another: different processes are not able
|
|
||||||
to cooperate with one another unless one sets up some means of communication
|
|
||||||
between them (such as by using sockets). If a lot of data must be transferred
|
|
||||||
between processes then this can be inefficient.
|
|
||||||
|
|
||||||
On the other hand, multiple threads within a single process are intimately
|
|
||||||
connected: they share their data but often can interfere badly with one another.
|
|
||||||
It is often argued that the only way to make multithreaded programming "easy" is
|
|
||||||
to avoid relying on any shared state and for the threads to only communicate by
|
|
||||||
passing messages to each other.
|
|
||||||
|
|
||||||
CPython has a *Global Interpreter Lock* (GIL) which in many ways makes threading
|
|
||||||
easier than it is in most languages by making sure that only one thread can
|
|
||||||
manipulate the interpreter's objects at a time. As a result, it is often safe
|
|
||||||
to let multiple threads access data without using any additional locking as one
|
|
||||||
would need to in a language such as C.
|
|
||||||
|
|
||||||
One downside of the GIL is that on multi-processor (or multi-core) systems a
|
|
||||||
multithreaded Python program can only make use of one processor at a time unless
|
|
||||||
your application makes heavy use of I/O which effectively side-steps this. This
|
|
||||||
is a problem that can be overcome by using multiple processes instead.
|
|
||||||
|
|
||||||
This package allows one to write multi-process programs using much the same API
|
|
||||||
that one uses for writing threaded programs.
|
|
||||||
|
|
||||||
|
|
||||||
Forking and spawning
|
|
||||||
~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
There are two ways of creating a new process in Python:
|
|
||||||
|
|
||||||
* The current process can *fork* a new child process by using the
|
|
||||||
:func:`os.fork` function. This effectively creates an identical copy of the
|
|
||||||
current process which is now able to go off and perform some task set by the
|
|
||||||
parent process. This means that the child process inherits *copies* of all
|
|
||||||
variables that the parent process had. However, :func:`os.fork` is not
|
|
||||||
available on every platform: in particular Windows does not support it.
|
|
||||||
|
|
||||||
* Alternatively, the current process can spawn a completely new Python
|
|
||||||
interpreter by using the :mod:`subprocess` module or one of the
|
|
||||||
:func:`os.spawn*` functions. Getting this new interpreter in to a fit state
|
|
||||||
to perform the task set for it by its parent process is, however, a bit of a
|
|
||||||
challenge.
|
|
||||||
|
|
||||||
The :mod:`multiprocessing` module uses :func:`os.fork` if it is available since
|
|
||||||
it makes life a lot simpler. Forking the process is also more efficient in
|
|
||||||
terms of memory usage and the time needed to create the new process.
|
|
||||||
|
|
||||||
|
|
||||||
The :class:`Process` class
|
The :class:`Process` class
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
In :mod:`multiprocessing`, processes are spawned by creating a :class:`Process`
|
In :mod:`multiprocessing`, processes are spawned by creating a :class:`Process`
|
||||||
object and then calling its :meth:`Process.start` method. :class:`Process`
|
object and then calling its :meth:`~Process.start` method. :class:`Process`
|
||||||
follows the API of :class:`threading.Thread`. A trivial example of a
|
follows the API of :class:`threading.Thread`. A trivial example of a
|
||||||
multiprocess program is ::
|
multiprocess program is ::
|
||||||
|
|
||||||
|
|
@ -143,11 +86,12 @@ processes:
|
||||||
p.join()
|
p.join()
|
||||||
|
|
||||||
The two connection objects returned by :func:`Pipe` represent the two ends of
|
The two connection objects returned by :func:`Pipe` represent the two ends of
|
||||||
the pipe. Each connection object has :meth:`send` and :meth:`recv` methods
|
the pipe. Each connection object has :meth:`~Connection.send` and
|
||||||
(among others). Note that data in a pipe may become corrupted if two
|
:meth:`~Connection.recv` methods (among others). Note that data in a pipe
|
||||||
processes (or threads) try to read from or write to the *same* end of the
|
may become corrupted if two processes (or threads) try to read from or write
|
||||||
pipe at the same time. Of course there is no risk of corruption from
|
to the *same* end of the pipe at the same time. Of course there is no risk
|
||||||
processes using different ends of the pipe at the same time.
|
of corruption from processes using different ends of the pipe at the same
|
||||||
|
time.
|
||||||
|
|
||||||
|
|
||||||
Synchronization between processes
|
Synchronization between processes
|
||||||
|
|
@ -268,7 +212,7 @@ However, if you really do need to use some shared data then
|
||||||
Using a pool of workers
|
Using a pool of workers
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
The :class:`multiprocessing.pool.Pool()` class represens a pool of worker
|
The :class:`~multiprocessing.pool.Pool` class represents a pool of worker
|
||||||
processes. It has methods which allows tasks to be offloaded to the worker
|
processes. It has methods which allows tasks to be offloaded to the worker
|
||||||
processes in a few different ways.
|
processes in a few different ways.
|
||||||
|
|
||||||
|
|
@ -303,9 +247,9 @@ The :mod:`multiprocessing` package mostly replicates the API of the
|
||||||
:class:`threading.Thread`.
|
:class:`threading.Thread`.
|
||||||
|
|
||||||
The constructor should always be called with keyword arguments. *group*
|
The constructor should always be called with keyword arguments. *group*
|
||||||
should always be ``None``; it exists soley for compatibility with
|
should always be ``None``; it exists solely for compatibility with
|
||||||
:class:`threading.Thread`. *target* is the callable object to be invoked by
|
:class:`~threading.Thread`. *target* is the callable object to be invoked by
|
||||||
the :meth:`run()` method. It defaults to None, meaning nothing is
|
the :meth:`run()` method. It defaults to ``None``, meaning nothing is
|
||||||
called. *name* is the process name. By default, a unique name is constructed
|
called. *name* is the process name. By default, a unique name is constructed
|
||||||
of the form 'Process-N\ :sub:`1`:N\ :sub:`2`:...:N\ :sub:`k`' where N\
|
of the form 'Process-N\ :sub:`1`:N\ :sub:`2`:...:N\ :sub:`k`' where N\
|
||||||
:sub:`1`,N\ :sub:`2`,...,N\ :sub:`k` is a sequence of integers whose length
|
:sub:`1`,N\ :sub:`2`,...,N\ :sub:`k` is a sequence of integers whose length
|
||||||
|
|
@ -413,11 +357,11 @@ The :mod:`multiprocessing` package mostly replicates the API of the
|
||||||
|
|
||||||
Set the process's authentication key which must be a byte string.
|
Set the process's authentication key which must be a byte string.
|
||||||
|
|
||||||
.. method:: terminate()`
|
.. method:: terminate()
|
||||||
|
|
||||||
Terminate the process. On Unix this is done using the ``SIGTERM`` signal,
|
Terminate the process. On Unix this is done using the ``SIGTERM`` signal;
|
||||||
on Windows ``TerminateProcess()`` is used. Note that exit handlers and
|
on Windows :cfunc:`TerminateProcess` is used. Note that exit handlers and
|
||||||
finally clauses etc will not be executed.
|
finally clauses, etc., will not be executed.
|
||||||
|
|
||||||
Note that descendant processes of the process will *not* be terminated --
|
Note that descendant processes of the process will *not* be terminated --
|
||||||
they will simply become orphaned.
|
they will simply become orphaned.
|
||||||
|
|
@ -472,14 +416,17 @@ processes) or a queue (which allows multiple producers and consumers).
|
||||||
The :class:`Queue` and :class:`JoinableQueue` types are multi-producer,
|
The :class:`Queue` and :class:`JoinableQueue` types are multi-producer,
|
||||||
multi-consumer FIFO queues modelled on the :class:`Queue.Queue` class in the
|
multi-consumer FIFO queues modelled on the :class:`Queue.Queue` class in the
|
||||||
standard library. They differ in that :class:`Queue` lacks the
|
standard library. They differ in that :class:`Queue` lacks the
|
||||||
:meth:`task_done` and :meth:`join` methods introduced into Python 2.5's
|
:meth:`~Queue.Queue.task_done` and :meth:`~Queue.Queue.join` methods introduced
|
||||||
:class:`Queue.Queue` class.
|
into Python 2.5's :class:`Queue.Queue` class.
|
||||||
|
|
||||||
If you use :class:`JoinableQueue` then you **must** call
|
If you use :class:`JoinableQueue` then you **must** call
|
||||||
:meth:`JoinableQueue.task_done` for each task removed from the queue or else the
|
:meth:`JoinableQueue.task_done` for each task removed from the queue or else the
|
||||||
semaphore used to count the number of unfinished tasks may eventually overflow
|
semaphore used to count the number of unfinished tasks may eventually overflow
|
||||||
raising an exception.
|
raising an exception.
|
||||||
|
|
||||||
|
Note that one can also create a shared queue by using a manager object -- see
|
||||||
|
:ref:`multiprocessing-managers`.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
:mod:`multiprocessing` uses the usual :exc:`Queue.Empty` and
|
:mod:`multiprocessing` uses the usual :exc:`Queue.Empty` and
|
||||||
|
|
@ -509,9 +456,6 @@ raising an exception.
|
||||||
Note that a queue created using a manager does not have this issue. See
|
Note that a queue created using a manager does not have this issue. See
|
||||||
:ref:`multiprocessing-programming`.
|
:ref:`multiprocessing-programming`.
|
||||||
|
|
||||||
Note that one can also create a shared queue by using a manager object -- see
|
|
||||||
:ref:`multiprocessing-managers`.
|
|
||||||
|
|
||||||
For an example of the usage of queues for interprocess communication see
|
For an example of the usage of queues for interprocess communication see
|
||||||
:ref:`multiprocessing-examples`.
|
:ref:`multiprocessing-examples`.
|
||||||
|
|
||||||
|
|
@ -537,7 +481,7 @@ For an example of the usage of queues for interprocess communication see
|
||||||
standard library's :mod:`Queue` module are raised to signal timeouts.
|
standard library's :mod:`Queue` module are raised to signal timeouts.
|
||||||
|
|
||||||
:class:`Queue` implements all the methods of :class:`Queue.Queue` except for
|
:class:`Queue` implements all the methods of :class:`Queue.Queue` except for
|
||||||
:meth:`task_done` and :meth:`join`.
|
:meth:`~Queue.Queue.task_done` and :meth:`~Queue.Queue.join`.
|
||||||
|
|
||||||
.. method:: qsize()
|
.. method:: qsize()
|
||||||
|
|
||||||
|
|
@ -557,10 +501,10 @@ For an example of the usage of queues for interprocess communication see
|
||||||
Return ``True`` if the queue is full, ``False`` otherwise. Because of
|
Return ``True`` if the queue is full, ``False`` otherwise. Because of
|
||||||
multithreading/multiprocessing semantics, this is not reliable.
|
multithreading/multiprocessing semantics, this is not reliable.
|
||||||
|
|
||||||
.. method:: put(item[, block[, timeout]])`
|
.. method:: put(item[, block[, timeout]])
|
||||||
|
|
||||||
Put item into the queue. If optional args *block* is ``True`` (the
|
Put item into the queue. If the optional argument *block* is ``True``
|
||||||
default) and *timeout* is ``None`` (the default), block if necessary until
|
(the default) and *timeout* is ``None`` (the default), block if necessary until
|
||||||
a free slot is available. If *timeout* is a positive number, it blocks at
|
a free slot is available. If *timeout* is a positive number, it blocks at
|
||||||
most *timeout* seconds and raises the :exc:`Queue.Full` exception if no
|
most *timeout* seconds and raises the :exc:`Queue.Full` exception if no
|
||||||
free slot was available within that time. Otherwise (*block* is
|
free slot was available within that time. Otherwise (*block* is
|
||||||
|
|
@ -605,13 +549,13 @@ For an example of the usage of queues for interprocess communication see
|
||||||
|
|
||||||
By default if a process is not the creator of the queue then on exit it
|
By default if a process is not the creator of the queue then on exit it
|
||||||
will attempt to join the queue's background thread. The process can call
|
will attempt to join the queue's background thread. The process can call
|
||||||
:meth:`cancel_join_thread()` to make :meth:`join_thread()` do nothing.
|
:meth:`cancel_join_thread` to make :meth:`join_thread` do nothing.
|
||||||
|
|
||||||
.. method:: cancel_join_thread()
|
.. method:: cancel_join_thread()
|
||||||
|
|
||||||
Prevent :meth:`join_thread` from blocking. In particular, this prevents
|
Prevent :meth:`join_thread` from blocking. In particular, this prevents
|
||||||
the background thread from being joined automatically when the process
|
the background thread from being joined automatically when the process
|
||||||
exits -- see :meth:`join_thread()`.
|
exits -- see :meth:`join_thread`.
|
||||||
|
|
||||||
|
|
||||||
.. class:: JoinableQueue([maxsize])
|
.. class:: JoinableQueue([maxsize])
|
||||||
|
|
@ -622,13 +566,13 @@ For an example of the usage of queues for interprocess communication see
|
||||||
.. method:: task_done()
|
.. method:: task_done()
|
||||||
|
|
||||||
Indicate that a formerly enqueued task is complete. Used by queue consumer
|
Indicate that a formerly enqueued task is complete. Used by queue consumer
|
||||||
threads. For each :meth:`get` used to fetch a task, a subsequent call to
|
threads. For each :meth:`~Queue.get` used to fetch a task, a subsequent
|
||||||
:meth:`task_done` tells the queue that the processing on the task is
|
call to :meth:`task_done` tells the queue that the processing on the task
|
||||||
complete.
|
is complete.
|
||||||
|
|
||||||
If a :meth:`join` is currently blocking, it will resume when all items
|
If a :meth:`~Queue.join` is currently blocking, it will resume when all
|
||||||
have been processed (meaning that a :meth:`task_done` call was received
|
items have been processed (meaning that a :meth:`task_done` call was
|
||||||
for every item that had been :meth:`put` into the queue).
|
received for every item that had been :meth:`~Queue.put` into the queue).
|
||||||
|
|
||||||
Raises a :exc:`ValueError` if called more times than there were items
|
Raises a :exc:`ValueError` if called more times than there were items
|
||||||
placed in the queue.
|
placed in the queue.
|
||||||
|
|
@ -642,7 +586,7 @@ For an example of the usage of queues for interprocess communication see
|
||||||
queue. The count goes down whenever a consumer thread calls
|
queue. The count goes down whenever a consumer thread calls
|
||||||
:meth:`task_done` to indicate that the item was retrieved and all work on
|
:meth:`task_done` to indicate that the item was retrieved and all work on
|
||||||
it is complete. When the count of unfinished tasks drops to zero,
|
it is complete. When the count of unfinished tasks drops to zero,
|
||||||
:meth:`join` unblocks.
|
:meth:`~Queue.join` unblocks.
|
||||||
|
|
||||||
|
|
||||||
Miscellaneous
|
Miscellaneous
|
||||||
|
|
@ -684,17 +628,17 @@ Miscellaneous
|
||||||
freeze_support()
|
freeze_support()
|
||||||
Process(target=f).start()
|
Process(target=f).start()
|
||||||
|
|
||||||
If the :func:`freeze_support()` line is missed out then trying to run the
|
If the ``freeze_support()`` line is missed out then trying to run the frozen
|
||||||
frozen executable will raise :exc:`RuntimeError`.
|
executable will raise :exc:`RuntimeError`.
|
||||||
|
|
||||||
If the module is being run normally by the Python interpreter then
|
If the module is being run normally by the Python interpreter then
|
||||||
:func:`freeze_support()` has no effect.
|
:func:`freeze_support` has no effect.
|
||||||
|
|
||||||
.. function:: set_executable()
|
.. function:: set_executable()
|
||||||
|
|
||||||
Sets the path of the python interpreter to use when starting a child process.
|
Sets the path of the python interpreter to use when starting a child process.
|
||||||
(By default `sys.executable` is used). Embedders will probably need to do
|
(By default :data:`sys.executable` is used). Embedders will probably need to
|
||||||
some thing like ::
|
do some thing like ::
|
||||||
|
|
||||||
setExecutable(os.path.join(sys.exec_prefix, 'pythonw.exe'))
|
setExecutable(os.path.join(sys.exec_prefix, 'pythonw.exe'))
|
||||||
|
|
||||||
|
|
@ -715,7 +659,7 @@ Connection Objects
|
||||||
Connection objects allow the sending and receiving of picklable objects or
|
Connection objects allow the sending and receiving of picklable objects or
|
||||||
strings. They can be thought of as message oriented connected sockets.
|
strings. They can be thought of as message oriented connected sockets.
|
||||||
|
|
||||||
Connection objects usually created using :func:`Pipe()` -- see also
|
Connection objects usually created using :func:`Pipe` -- see also
|
||||||
:ref:`multiprocessing-listeners-clients`.
|
:ref:`multiprocessing-listeners-clients`.
|
||||||
|
|
||||||
.. class:: Connection
|
.. class:: Connection
|
||||||
|
|
@ -812,9 +756,10 @@ For example:
|
||||||
receives, which can be a security risk unless you can trust the process
|
receives, which can be a security risk unless you can trust the process
|
||||||
which sent the message.
|
which sent the message.
|
||||||
|
|
||||||
Therefore, unless the connection object was produced using :func:`Pipe()`
|
Therefore, unless the connection object was produced using :func:`Pipe` you
|
||||||
you should only use the `recv()` and `send()` methods after performing some
|
should only use the :meth:`~Connection.recv` and :meth:`~Connection.send`
|
||||||
sort of authentication. See :ref:`multiprocessing-auth-keys`.
|
methods after performing some sort of authentication. See
|
||||||
|
:ref:`multiprocessing-auth-keys`.
|
||||||
|
|
||||||
.. warning::
|
.. warning::
|
||||||
|
|
||||||
|
|
@ -827,8 +772,8 @@ Synchronization primitives
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
Generally synchronization primitives are not as necessary in a multiprocess
|
Generally synchronization primitives are not as necessary in a multiprocess
|
||||||
program as they are in a mulithreaded program. See the documentation for the
|
program as they are in a mulithreaded program. See the documentation for
|
||||||
standard library's :mod:`threading` module.
|
:mod:`threading` module.
|
||||||
|
|
||||||
Note that one can also create synchronization primitives by using a manager
|
Note that one can also create synchronization primitives by using a manager
|
||||||
object -- see :ref:`multiprocessing-managers`.
|
object -- see :ref:`multiprocessing-managers`.
|
||||||
|
|
@ -842,7 +787,7 @@ object -- see :ref:`multiprocessing-managers`.
|
||||||
|
|
||||||
.. class:: Condition([lock])
|
.. class:: Condition([lock])
|
||||||
|
|
||||||
A condition variable: a clone of `threading.Condition`.
|
A condition variable: a clone of :class:`threading.Condition`.
|
||||||
|
|
||||||
If *lock* is specified then it should be a :class:`Lock` or :class:`RLock`
|
If *lock* is specified then it should be a :class:`Lock` or :class:`RLock`
|
||||||
object from :mod:`multiprocessing`.
|
object from :mod:`multiprocessing`.
|
||||||
|
|
@ -865,7 +810,7 @@ object -- see :ref:`multiprocessing-managers`.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
The :meth:`acquire()` method of :class:`BoundedSemaphore`, :class:`Lock`,
|
The :meth:`acquire` method of :class:`BoundedSemaphore`, :class:`Lock`,
|
||||||
:class:`RLock` and :class:`Semaphore` has a timeout parameter not supported
|
:class:`RLock` and :class:`Semaphore` has a timeout parameter not supported
|
||||||
by the equivalents in :mod:`threading`. The signature is
|
by the equivalents in :mod:`threading`. The signature is
|
||||||
``acquire(block=True, timeout=None)`` with keyword parameters being
|
``acquire(block=True, timeout=None)`` with keyword parameters being
|
||||||
|
|
@ -891,7 +836,7 @@ Shared :mod:`ctypes` Objects
|
||||||
It is possible to create shared objects using shared memory which can be
|
It is possible to create shared objects using shared memory which can be
|
||||||
inherited by child processes.
|
inherited by child processes.
|
||||||
|
|
||||||
.. function:: Value(typecode_or_type[, lock[, *args]])
|
.. function:: Value(typecode_or_type[, *args, lock]])
|
||||||
|
|
||||||
Return a :mod:`ctypes` object allocated from shared memory. By default the
|
Return a :mod:`ctypes` object allocated from shared memory. By default the
|
||||||
return value is actually a synchronized wrapper for the object.
|
return value is actually a synchronized wrapper for the object.
|
||||||
|
|
@ -983,7 +928,7 @@ processes.
|
||||||
attributes which allow one to use it to store and retrieve strings -- see
|
attributes which allow one to use it to store and retrieve strings -- see
|
||||||
documentation for :mod:`ctypes`.
|
documentation for :mod:`ctypes`.
|
||||||
|
|
||||||
.. function:: Array(typecode_or_type, size_or_initializer[, lock[, *args]])
|
.. function:: Array(typecode_or_type, size_or_initializer[, *args[, lock]])
|
||||||
|
|
||||||
The same as :func:`RawArray` except that depending on the value of *lock* a
|
The same as :func:`RawArray` except that depending on the value of *lock* a
|
||||||
process-safe synchronization wrapper may be returned instead of a raw ctypes
|
process-safe synchronization wrapper may be returned instead of a raw ctypes
|
||||||
|
|
@ -1025,11 +970,11 @@ processes.
|
||||||
:class:`multiprocessing.RLock` object is created automatically.
|
:class:`multiprocessing.RLock` object is created automatically.
|
||||||
|
|
||||||
A synchronized wrapper will have two methods in addition to those of the
|
A synchronized wrapper will have two methods in addition to those of the
|
||||||
object it wraps: :meth:`get_obj()` returns the wrapped object and
|
object it wraps: :meth:`get_obj` returns the wrapped object and
|
||||||
:meth:`get_lock()` returns the lock object used for synchronization.
|
:meth:`get_lock` returns the lock object used for synchronization.
|
||||||
|
|
||||||
Note that accessing the ctypes object through the wrapper can be a lot slower
|
Note that accessing the ctypes object through the wrapper can be a lot slower
|
||||||
han accessing the raw ctypes object.
|
than accessing the raw ctypes object.
|
||||||
|
|
||||||
|
|
||||||
The table below compares the syntax for creating shared ctypes objects from
|
The table below compares the syntax for creating shared ctypes objects from
|
||||||
|
|
@ -1105,10 +1050,10 @@ objects*. Other processes can access the shared objects by using proxies.
|
||||||
|
|
||||||
.. function:: multiprocessing.Manager()
|
.. function:: multiprocessing.Manager()
|
||||||
|
|
||||||
Returns a started :class:`SyncManager` object which can be used for sharing
|
Returns a started :class:`~multiprocessing.managers.SyncManager` object which
|
||||||
objects between processes. The returned manager object corresponds to a
|
can be used for sharing objects between processes. The returned manager
|
||||||
spawned child process and has methods which will create shared objects and
|
object corresponds to a spawned child process and has methods which will
|
||||||
return corresponding proxies.
|
create shared objects and return corresponding proxies.
|
||||||
|
|
||||||
.. module:: multiprocessing.managers
|
.. module:: multiprocessing.managers
|
||||||
:synopsis: Share data between process with shared objects.
|
:synopsis: Share data between process with shared objects.
|
||||||
|
|
@ -1148,7 +1093,7 @@ their parent process exits. The manager classes are defined in the
|
||||||
.. method:: shutdown()
|
.. method:: shutdown()
|
||||||
|
|
||||||
Stop the process used by the manager. This is only available if
|
Stop the process used by the manager. This is only available if
|
||||||
meth:`start` has been used to start the server process.
|
:meth:`start` has been used to start the server process.
|
||||||
|
|
||||||
This can be called multiple times.
|
This can be called multiple times.
|
||||||
|
|
||||||
|
|
@ -1162,12 +1107,12 @@ their parent process exits. The manager classes are defined in the
|
||||||
|
|
||||||
*callable* is a callable used for creating objects for this type
|
*callable* is a callable used for creating objects for this type
|
||||||
identifier. If a manager instance will be created using the
|
identifier. If a manager instance will be created using the
|
||||||
:meth:`from_address()` classmethod or if the *create_method* argument is
|
:meth:`from_address` classmethod or if the *create_method* argument is
|
||||||
``False`` then this can be left as ``None``.
|
``False`` then this can be left as ``None``.
|
||||||
|
|
||||||
*proxytype* is a subclass of :class:`multiprocessing.managers.BaseProxy`
|
*proxytype* is a subclass of :class:`BaseProxy` which is used to create
|
||||||
which is used to create proxies for shared objects with this *typeid*. If
|
proxies for shared objects with this *typeid*. If ``None`` then a proxy
|
||||||
``None`` then a proxy class is created automatically.
|
class is created automatically.
|
||||||
|
|
||||||
*exposed* is used to specify a sequence of method names which proxies for
|
*exposed* is used to specify a sequence of method names which proxies for
|
||||||
this typeid should be allowed to access using
|
this typeid should be allowed to access using
|
||||||
|
|
@ -1175,7 +1120,7 @@ their parent process exits. The manager classes are defined in the
|
||||||
:attr:`proxytype._exposed_` is used instead if it exists.) In the case
|
:attr:`proxytype._exposed_` is used instead if it exists.) In the case
|
||||||
where no exposed list is specified, all "public methods" of the shared
|
where no exposed list is specified, all "public methods" of the shared
|
||||||
object will be accessible. (Here a "public method" means any attribute
|
object will be accessible. (Here a "public method" means any attribute
|
||||||
which has a ``__call__()`` method and whose name does not begin with
|
which has a :meth:`__call__` method and whose name does not begin with
|
||||||
``'_'``.)
|
``'_'``.)
|
||||||
|
|
||||||
*method_to_typeid* is a mapping used to specify the return type of those
|
*method_to_typeid* is a mapping used to specify the return type of those
|
||||||
|
|
@ -1200,7 +1145,7 @@ their parent process exits. The manager classes are defined in the
|
||||||
|
|
||||||
A subclass of :class:`BaseManager` which can be used for the synchronization
|
A subclass of :class:`BaseManager` which can be used for the synchronization
|
||||||
of processes. Objects of this type are returned by
|
of processes. Objects of this type are returned by
|
||||||
:func:`multiprocessing.Manager()`.
|
:func:`multiprocessing.Manager`.
|
||||||
|
|
||||||
It also supports creation of shared lists and dictionaries.
|
It also supports creation of shared lists and dictionaries.
|
||||||
|
|
||||||
|
|
@ -1231,7 +1176,7 @@ their parent process exits. The manager classes are defined in the
|
||||||
|
|
||||||
.. method:: Queue([maxsize])
|
.. method:: Queue([maxsize])
|
||||||
|
|
||||||
Create a shared `Queue.Queue` object and return a proxy for it.
|
Create a shared :class:`Queue.Queue` object and return a proxy for it.
|
||||||
|
|
||||||
.. method:: RLock()
|
.. method:: RLock()
|
||||||
|
|
||||||
|
|
@ -1244,7 +1189,7 @@ their parent process exits. The manager classes are defined in the
|
||||||
|
|
||||||
.. method:: Array(typecode, sequence)
|
.. method:: Array(typecode, sequence)
|
||||||
|
|
||||||
Create an array and return a proxy for it. (*format* is ignored.)
|
Create an array and return a proxy for it.
|
||||||
|
|
||||||
.. method:: Value(typecode, value)
|
.. method:: Value(typecode, value)
|
||||||
|
|
||||||
|
|
@ -1285,8 +1230,8 @@ Customized managers
|
||||||
>>>>>>>>>>>>>>>>>>>
|
>>>>>>>>>>>>>>>>>>>
|
||||||
|
|
||||||
To create one's own manager, one creates a subclass of :class:`BaseManager` and
|
To create one's own manager, one creates a subclass of :class:`BaseManager` and
|
||||||
use the :meth:`resgister()` classmethod to register new types or callables with
|
use the :meth:`~BaseManager.resgister` classmethod to register new types or
|
||||||
the manager class. For example::
|
callables with the manager class. For example::
|
||||||
|
|
||||||
from multiprocessing.managers import BaseManager
|
from multiprocessing.managers import BaseManager
|
||||||
|
|
||||||
|
|
@ -1385,7 +1330,7 @@ itself. This means, for example, that one shared object can contain a second::
|
||||||
|
|
||||||
>>> a = manager.list()
|
>>> a = manager.list()
|
||||||
>>> b = manager.list()
|
>>> b = manager.list()
|
||||||
>>> a.append(b) # referent of `a` now contains referent of `b`
|
>>> a.append(b) # referent of a now contains referent of b
|
||||||
>>> print a, b
|
>>> print a, b
|
||||||
[[]] []
|
[[]] []
|
||||||
>>> b.append('hello')
|
>>> b.append('hello')
|
||||||
|
|
@ -1432,7 +1377,7 @@ itself. This means, for example, that one shared object can contain a second::
|
||||||
Note in particular that an exception will be raised if *methodname* has
|
Note in particular that an exception will be raised if *methodname* has
|
||||||
not been *exposed*
|
not been *exposed*
|
||||||
|
|
||||||
An example of the usage of :meth:`_call_method()`::
|
An example of the usage of :meth:`_call_method`::
|
||||||
|
|
||||||
>>> l = manager.list(range(10))
|
>>> l = manager.list(range(10))
|
||||||
>>> l._call_method('__len__')
|
>>> l._call_method('__len__')
|
||||||
|
|
@ -1476,7 +1421,7 @@ Process Pools
|
||||||
:synopsis: Create pools of processes.
|
:synopsis: Create pools of processes.
|
||||||
|
|
||||||
One can create a pool of processes which will carry out tasks submitted to it
|
One can create a pool of processes which will carry out tasks submitted to it
|
||||||
with the :class:`Pool` class in :mod:`multiprocess.pool`.
|
with the :class:`Pool` class.
|
||||||
|
|
||||||
.. class:: multiprocessing.Pool([processes[, initializer[, initargs]]])
|
.. class:: multiprocessing.Pool([processes[, initializer[, initargs]]])
|
||||||
|
|
||||||
|
|
@ -1514,7 +1459,7 @@ with the :class:`Pool` class in :mod:`multiprocess.pool`.
|
||||||
|
|
||||||
.. method:: map_async(func, iterable[, chunksize[, callback]])
|
.. method:: map_async(func, iterable[, chunksize[, callback]])
|
||||||
|
|
||||||
A variant of the :meth:`.map` method which returns a result object.
|
A variant of the :meth:`map` method which returns a result object.
|
||||||
|
|
||||||
If *callback* is specified then it should be a callable which accepts a
|
If *callback* is specified then it should be a callable which accepts a
|
||||||
single argument. When the result becomes ready *callback* is applied to
|
single argument. When the result becomes ready *callback* is applied to
|
||||||
|
|
@ -1622,7 +1567,7 @@ Usually message passing between processes is done using queues or by using
|
||||||
However, the :mod:`multiprocessing.connection` module allows some extra
|
However, the :mod:`multiprocessing.connection` module allows some extra
|
||||||
flexibility. It basically gives a high level message oriented API for dealing
|
flexibility. It basically gives a high level message oriented API for dealing
|
||||||
with sockets or Windows named pipes, and also has support for *digest
|
with sockets or Windows named pipes, and also has support for *digest
|
||||||
authentication* using the :mod:`hmac` module from the standard library.
|
authentication* using the :mod:`hmac` module.
|
||||||
|
|
||||||
|
|
||||||
.. function:: deliver_challenge(connection, authkey)
|
.. function:: deliver_challenge(connection, authkey)
|
||||||
|
|
@ -1645,7 +1590,7 @@ authentication* using the :mod:`hmac` module from the standard library.
|
||||||
.. function:: Client(address[, family[, authenticate[, authkey]]])
|
.. function:: Client(address[, family[, authenticate[, authkey]]])
|
||||||
|
|
||||||
Attempt to set up a connection to the listener which is using address
|
Attempt to set up a connection to the listener which is using address
|
||||||
*address*, returning a :class:`Connection`.
|
*address*, returning a :class:`~multiprocessing.Connection`.
|
||||||
|
|
||||||
The type of the connection is determined by *family* argument, but this can
|
The type of the connection is determined by *family* argument, but this can
|
||||||
generally be omitted since it can usually be inferred from the format of
|
generally be omitted since it can usually be inferred from the format of
|
||||||
|
|
@ -1721,15 +1666,6 @@ The module defines two exceptions:
|
||||||
|
|
||||||
Exception raised when there is an authentication error.
|
Exception raised when there is an authentication error.
|
||||||
|
|
||||||
.. exception:: BufferTooShort
|
|
||||||
|
|
||||||
Exception raise by the :meth:`Connection.recv_bytes_into` method of a
|
|
||||||
connection object when the supplied buffer object is too small for the
|
|
||||||
message read.
|
|
||||||
|
|
||||||
If *e* is an instance of :exc:`BufferTooShort` then ``e.args[0]`` will give
|
|
||||||
the message as a byte string.
|
|
||||||
|
|
||||||
|
|
||||||
**Examples**
|
**Examples**
|
||||||
|
|
||||||
|
|
@ -1780,10 +1716,10 @@ server::
|
||||||
Address Formats
|
Address Formats
|
||||||
>>>>>>>>>>>>>>>
|
>>>>>>>>>>>>>>>
|
||||||
|
|
||||||
* An ``'AF_INET'`` address is a tuple of the form ``(hostname, port)``` where
|
* An ``'AF_INET'`` address is a tuple of the form ``(hostname, port)`` where
|
||||||
*hostname* is a string and *port* is an integer.
|
*hostname* is a string and *port* is an integer.
|
||||||
|
|
||||||
* An ``'AF_UNIX'``` address is a string representing a filename on the
|
* An ``'AF_UNIX'`` address is a string representing a filename on the
|
||||||
filesystem.
|
filesystem.
|
||||||
|
|
||||||
* An ``'AF_PIPE'`` address is a string of the form
|
* An ``'AF_PIPE'`` address is a string of the form
|
||||||
|
|
@ -1812,11 +1748,11 @@ authentication key. (Demonstrating that both ends are using the same key does
|
||||||
|
|
||||||
If authentication is requested but do authentication key is specified then the
|
If authentication is requested but do authentication key is specified then the
|
||||||
return value of ``current_process().get_auth_key`` is used (see
|
return value of ``current_process().get_auth_key`` is used (see
|
||||||
:class:`Process`). This value will automatically inherited by any
|
:class:`~multiprocessing.Process`). This value will automatically inherited by
|
||||||
:class:`Process` object that the current process creates. This means that (by
|
any :class:`~multiprocessing.Process` object that the current process creates.
|
||||||
default) all processes of a multi-process program will share a single
|
This means that (by default) all processes of a multi-process program will share
|
||||||
authentication key which can be used when setting up connections between the
|
a single authentication key which can be used when setting up connections
|
||||||
themselves.
|
between the themselves.
|
||||||
|
|
||||||
Suitable authentication keys can also be generated by using :func:`os.urandom`.
|
Suitable authentication keys can also be generated by using :func:`os.urandom`.
|
||||||
|
|
||||||
|
|
@ -1866,7 +1802,7 @@ The :mod:`multiprocessing.dummy` module
|
||||||
:synopsis: Dumb wrapper around threading.
|
:synopsis: Dumb wrapper around threading.
|
||||||
|
|
||||||
:mod:`multiprocessing.dummy` replicates the API of :mod:`multiprocessing` but is
|
:mod:`multiprocessing.dummy` replicates the API of :mod:`multiprocessing` but is
|
||||||
no more than a wrapper around the `threading` module.
|
no more than a wrapper around the :mod:`threading` module.
|
||||||
|
|
||||||
|
|
||||||
.. _multiprocessing-programming:
|
.. _multiprocessing-programming:
|
||||||
|
|
@ -1912,7 +1848,7 @@ Joining zombie processes
|
||||||
|
|
||||||
Better to inherit than pickle/unpickle
|
Better to inherit than pickle/unpickle
|
||||||
|
|
||||||
On Windows many of types from :mod:`multiprocessing` need to be picklable so
|
On Windows many types from :mod:`multiprocessing` need to be picklable so
|
||||||
that child processes can use them. However, one should generally avoid
|
that child processes can use them. However, one should generally avoid
|
||||||
sending shared objects to other processes using pipes or queues. Instead
|
sending shared objects to other processes using pipes or queues. Instead
|
||||||
you should arrange the program so that a process which need access to a
|
you should arrange the program so that a process which need access to a
|
||||||
|
|
@ -1926,8 +1862,7 @@ Avoid terminating processes
|
||||||
processes.
|
processes.
|
||||||
|
|
||||||
Therefore it is probably best to only consider using
|
Therefore it is probably best to only consider using
|
||||||
:meth:`Process.terminate()` on processes which never use any shared
|
:meth:`Process.terminate` on processes which never use any shared resources.
|
||||||
resources.
|
|
||||||
|
|
||||||
Joining processes that use queues
|
Joining processes that use queues
|
||||||
|
|
||||||
|
|
@ -1959,7 +1894,7 @@ Joining processes that use queues
|
||||||
A fix here would be to swap the last two lines round (or simply remove the
|
A fix here would be to swap the last two lines round (or simply remove the
|
||||||
``p.join()`` line).
|
``p.join()`` line).
|
||||||
|
|
||||||
Explicity pass resources to child processes
|
Explicitly pass resources to child processes
|
||||||
|
|
||||||
On Unix a child process can make use of a shared resource created in a
|
On Unix a child process can make use of a shared resource created in a
|
||||||
parent process using a global resource. However, it is better to pass the
|
parent process using a global resource. However, it is better to pass the
|
||||||
|
|
@ -2050,7 +1985,7 @@ Safe importing of main module
|
||||||
p = Process(target=foo)
|
p = Process(target=foo)
|
||||||
p.start()
|
p.start()
|
||||||
|
|
||||||
(The :func:`freeze_support()` line can be omitted if the program will be run
|
(The ``freeze_support()`` line can be omitted if the program will be run
|
||||||
normally instead of frozen.)
|
normally instead of frozen.)
|
||||||
|
|
||||||
This allows the newly spawned Python interpreter to safely import the module
|
This allows the newly spawned Python interpreter to safely import the module
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue