Commit 4523968b authored by Jesse Noller's avatar Jesse Noller

Merge r67419 to py3k, mp doc fixes

parent 7ca7cb48
...@@ -24,6 +24,29 @@ Windows. ...@@ -24,6 +24,29 @@ Windows.
import it will result in an :exc:`ImportError`. See import it will result in an :exc:`ImportError`. See
:issue:`3770` for additional information. :issue:`3770` for additional information.
.. note::
Functionality within this package requires that the ``__main__`` method be
importable by the children. This is covered in :ref:`multiprocessing-programming`
however it is worth pointing out here. This means that some examples, such
as the :class:`multiprocessing.Pool` examples will not work in the
interactive interpreter. For example::
>>> from multiprocessing import Pool
>>> p = Pool(5)
>>> def f(x):
... return x*x
...
>>> p.map(f, [1,2,3])
Process PoolWorker-1:
Process PoolWorker-2:
Traceback (most recent call last):
Traceback (most recent call last):
AttributeError: 'module' object has no attribute 'f'
AttributeError: 'module' object has no attribute 'f'
AttributeError: 'module' object has no attribute 'f'
The :class:`Process` class The :class:`Process` class
~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~
...@@ -42,7 +65,26 @@ multiprocess program is :: ...@@ -42,7 +65,26 @@ multiprocess program is ::
p.start() p.start()
p.join() p.join()
Here the function ``f`` is run in a child process. To show the individual process IDs involved, here is an expanded example::
from multiprocessing import Process
import os
def info(title):
print title
print 'module name:', __name__
print 'parent process:', os.getppid()
print 'process id:', os.getpid()
def f(name):
info('function f')
print 'hello', name
if __name__ == '__main__':
info('main line')
p = Process(target=f, args=('bob',))
p.start()
p.join()
For an explanation of why (on Windows) the ``if __name__ == '__main__'`` part is For an explanation of why (on Windows) the ``if __name__ == '__main__'`` part is
necessary, see :ref:`multiprocessing-programming`. necessary, see :ref:`multiprocessing-programming`.
...@@ -233,8 +275,8 @@ For example:: ...@@ -233,8 +275,8 @@ For example::
if __name__ == '__main__': if __name__ == '__main__':
pool = Pool(processes=4) # start 4 worker processes pool = Pool(processes=4) # start 4 worker processes
result = pool.apply_async(f, [10]) # evaluate "f(10)" asynchronously result = pool.apply_async(f, [10]) # evaluate "f(10)" asynchronously
print(result.get(timeout=1)) # prints "100" unless your computer is *very* slow print result.get(timeout=1) # prints "100" unless your computer is *very* slow
print(pool.map(f, range(10))) # prints "[0, 1, 4,..., 81]" print pool.map(f, range(10)) # prints "[0, 1, 4,..., 81]"
Reference Reference
...@@ -305,7 +347,7 @@ The :mod:`multiprocessing` package mostly replicates the API of the ...@@ -305,7 +347,7 @@ The :mod:`multiprocessing` package mostly replicates the API of the
semantics. Multiple processes may be given the same name. The initial semantics. Multiple processes may be given the same name. The initial
name is set by the constructor. name is set by the constructor.
.. method:: is_alive() .. method:: is_alive
Return whether the process is alive. Return whether the process is alive.
...@@ -815,6 +857,9 @@ object -- see :ref:`multiprocessing-managers`. ...@@ -815,6 +857,9 @@ object -- see :ref:`multiprocessing-managers`.
specifies a timeout in seconds. If *block* is ``False`` then *timeout* is specifies a timeout in seconds. If *block* is ``False`` then *timeout* is
ignored. ignored.
Note that on OS/X ``sem_timedwait`` is unsupported, so timeout arguments
for these will be ignored.
.. note:: .. note::
If the SIGINT signal generated by Ctrl-C arrives while the main thread is If the SIGINT signal generated by Ctrl-C arrives while the main thread is
...@@ -1087,6 +1132,27 @@ their parent process exits. The manager classes are defined in the ...@@ -1087,6 +1132,27 @@ their parent process exits. The manager classes are defined in the
A class method which creates a manager object referring to a pre-existing A class method which creates a manager object referring to a pre-existing
server process which is using the given address and authentication key. server process which is using the given address and authentication key.
.. method:: get_server()
Returns a :class:`Server` object which represents the actual server under
the control of the Manager. The :class:`Server` object supports the
:meth:`serve_forever` method::
>>> from multiprocessing.managers import BaseManager
>>> m = BaseManager(address=('', 50000), authkey='abc'))
>>> server = m.get_server()
>>> s.serve_forever()
:class:`Server` additionally have an :attr:`address` attribute.
.. method:: connect()
Connect a local manager object to a remote manager process::
>>> from multiprocessing.managers import BaseManager
>>> m = BaseManager(address='127.0.0.1', authkey='abc))
>>> m.connect()
.. 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
...@@ -1265,19 +1331,20 @@ remote clients can access:: ...@@ -1265,19 +1331,20 @@ remote clients can access::
>>> queue = queue.Queue() >>> queue = queue.Queue()
>>> class QueueManager(BaseManager): pass >>> class QueueManager(BaseManager): pass
... ...
>>> QueueManager.register('getQueue', callable=lambda:queue) >>> QueueManager.register('get_queue', callable=lambda:queue)
>>> m = QueueManager(address=('', 50000), authkey='abracadabra') >>> m = QueueManager(address=('', 50000), authkey='abracadabra')
>>> m.serveForever() >>> s = m.get_server()
>>> s.serveForever()
One client can access the server as follows:: One client can access the server as follows::
>>> from multiprocessing.managers import BaseManager >>> from multiprocessing.managers import BaseManager
>>> class QueueManager(BaseManager): pass >>> class QueueManager(BaseManager): pass
... ...
>>> QueueManager.register('getQueue') >>> QueueManager.register('get_queue')
>>> m = QueueManager.from_address(address=('foo.bar.org', 50000), >>> m = QueueManager(address=('foo.bar.org', 50000), authkey='abracadabra')
>>> authkey='abracadabra') >>> m.connect()
>>> queue = m.getQueue() >>> queue = m.get_queue()
>>> queue.put('hello') >>> queue.put('hello')
Another client can also use it:: Another client can also use it::
...@@ -1291,6 +1358,27 @@ Another client can also use it:: ...@@ -1291,6 +1358,27 @@ Another client can also use it::
>>> queue.get() >>> queue.get()
'hello' 'hello'
Local processes can also access that queue, using the code from above on the
client to access it remotely::
>>> from multiprocessing import Process, Queue
>>> from multiprocessing.managers import BaseManager
>>> class Worker(Process):
... def __init__(self, q):
... self.q = q
... super(Worker, self).__init__()
... def run(self):
... self.q.put('local hello')
...
>>> queue = Queue()
>>> w = Worker(queue)
>>> w.start()
>>> class QueueManager(BaseManager): pass
...
>>> QueueManager.register('get_queue', callable=lambda: queue)
>>> m = QueueManager(address=('', 50000), authkey='abracadabra')
>>> s = m.get_server()
>>> s.serve_forever()
Proxy Objects Proxy Objects
~~~~~~~~~~~~~ ~~~~~~~~~~~~~
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment