Commits

Jesse Noller committed bf2d192

Merge r67419 - mp doc fixes

Comments (0)

Files changed (2)

Doc/includes/mp_distributing.py

 _logger = logging.getLogger('distributing')
 _logger.propogate = 0
 
-util.fix_up_logger(_logger)
 _formatter = logging.Formatter(util.DEFAULT_LOGGING_FORMAT)
 _handler = logging.StreamHandler()
 _handler.setFormatter(_formatter)

Doc/library/multiprocessing.rst

     import it will result in an :exc:`ImportError`. See 
     :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
 ~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 follows the API of :class:`threading.Thread`.  A trivial example of a
 multiprocess program is ::
 
-   from multiprocessing import Process
-
-   def f(name):
-       print 'hello', name
-
-   if __name__ == '__main__':
-       p = Process(target=f, args=('bob',))
-       p.start()
-       p.join()
-
-Here the function ``f`` is run in a child process.
+    from multiprocessing import Process
+
+    def f(name):
+        print 'hello', name
+
+    if __name__ == '__main__':
+        p = Process(target=f, args=('bob',))
+        p.start()
+        p.join()
+
+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
 necessary, see :ref:`multiprocessing-programming`.
 
    if __name__ == '__main__':
        pool = Pool(processes=4)              # start 4 worker processes
-       result = pool.applyAsync(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 pool.map(f, range(10))          # prints "[0, 1, 4,..., 81]"
 
       semantics.  Multiple processes may be given the same name.  The initial
       name is set by the constructor.
 
-   .. method:: is_alive()
+   .. method:: is_alive
 
       Return whether the process is alive.
 
    acceptable.  If *block* is ``True`` and *timeout* is not ``None`` then it
    specifies a timeout in seconds.  If *block* is ``False`` then *timeout* is
    ignored.
+   
+   Note that on OS/X ``sem_timedwait`` is unsupported, so timeout arguments
+   for these will be ignored.
 
 .. note::
 
       A class method which creates a manager object referring to a pre-existing
       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()
 
       Stop the process used by the manager.  This is only available if
    >>> queue = Queue.Queue()
    >>> class QueueManager(BaseManager): pass
    ...
-   >>> QueueManager.register('getQueue', callable=lambda:queue)
+   >>> QueueManager.register('get_queue', callable=lambda:queue)
    >>> m = QueueManager(address=('', 50000), authkey='abracadabra')
-   >>> m.serveForever()
+   >>> s = m.get_server()
+   >>> s.serveForever()
 
 One client can access the server as follows::
 
    >>> from multiprocessing.managers import BaseManager
    >>> class QueueManager(BaseManager): pass
    ...
-   >>> QueueManager.register('getQueue')
-   >>> m = QueueManager.from_address(address=('foo.bar.org', 50000),
-   >>> authkey='abracadabra')
-   >>> queue = m.getQueue()
+   >>> QueueManager.register('get_queue')
+   >>> m = QueueManager(address=('foo.bar.org', 50000), authkey='abracadabra')
+   >>> m.connect()
+   >>> queue = m.get_queue()
    >>> queue.put('hello')
 
 Another client can also use it::
    >>> queue.get()
    '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
 ~~~~~~~~~~~~~
    The class of the result returned by :meth:`Pool.apply_async` and
    :meth:`Pool.map_async`.
 
-   .. method:: get([timeout)
+   .. method:: get([timeout])
 
       Return the result when it arrives.  If *timeout* is not ``None`` and the
       result does not arrive within *timeout* seconds then
    if __name__ == '__main__':
        pool = Pool(processes=4)              # start 4 worker processes
 
-       result = pool.applyAsync(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 pool.map(f, range(10))          # prints "[0, 1, 4,..., 81]"
        print it.next(timeout=1)              # prints "4" unless your computer is *very* slow
 
        import time
-       result = pool.applyAsync(time.sleep, (10,))
+       result = pool.apply_async(time.sleep, (10,))
        print result.get(timeout=1)           # raises TimeoutError
 
 
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.