]> granicus.if.org Git - python/commitdiff
Add entry for Barrier objects.
authorRaymond Hettinger <python@rcn.com>
Tue, 11 Jan 2011 19:59:46 +0000 (19:59 +0000)
committerRaymond Hettinger <python@rcn.com>
Tue, 11 Jan 2011 19:59:46 +0000 (19:59 +0000)
Doc/library/threading.rst
Doc/whatsnew/3.2.rst
Lib/threading.py

index 7f0628da6604c565208ebab66fcd4961d6db0c06..f50c2acb752a85d778512c14a249e570b3335adf 100644 (file)
@@ -868,7 +868,7 @@ As an example, here is a simple way to synchronize a client and server thread::
       constructor.
 
       The return value is an integer in the range 0 to *parties* -- 1, different
-      for each thrad.  This can be used to select a thread to do some special
+      for each thread.  This can be used to select a thread to do some special
       housekeeping, e.g.::
 
          i = barrier.wait()
index 84e5ee6f8e4425bc0c092566aee5c7808f28ec7c..e49db1ed1d4a20f046fb1efddcfc8e33a3bcbf45 100644 (file)
@@ -817,7 +817,49 @@ collections
 
   (Contributed by Raymond Hettinger.)
 
-.. XXX threading.py and Barrier objects
+threading
+---------
+
+The :mod:`threading` module has a new :class:`~threading.Barrier`
+synchronization class for making multiple threads wait until all of them have
+reached a common barrier point.  Barriers are useful for making sure that a task
+with multiple preconditions does not run until all of the predecessor tasks are
+complete.
+
+Barriers can work with an arbitrary number of threads.  This is a generalization
+of a `Rendezvous <http://en.wikipedia.org/wiki/Synchronous_rendezvous>`_ which
+is defined for only two threads.
+
+The barrier is designed to be cyclic, making it reusable once all of the
+waiting threads are released.
+
+If any of the predecessor tasks can hang or be delayed, a barrier can be created
+with an optional *timeout* parameter.  Then if the timeout period elapses before
+all the predecessor tasks reach the barrier point, all waiting threads are
+released and a :exc:`~threading.BrokenBarrierError` exception is raised.
+
+Example of using barriers::
+
+    def get_votes(site):
+        ballots = conduct_election(site)
+        all_polls_closed.wait()        # do not count until all polls are closed
+        summarize(ballots)
+
+    all_polls_closed = Barrier(len(sites))
+    for site in sites(get_votes(site)):
+        Thread(target=get_votes, args=(site,)).start()
+
+In this example, the barrier enforces a rule that votes cannot be counted at any
+polling site until all polls are closed.  Notice how a solution with a barrier
+is similar to one with :meth:`threading.Thread.join`, but the threads stay alive
+and continue to do work (summarizing ballots) after the barrier point is
+crossed.
+
+See `Barrier Synchronization Patterns
+<http://parlab.eecs.berkeley.edu/wiki/_media/patterns/paraplop_g1_3.pdf>`_
+for more examples of how barriers can be used in parallel computing.
+
+(Contributed by Kristján Valur Jónsson in :issue:`8777`.)
 
 datetime
 --------
index 392ad141de60f0624e79b54240b00126fc5b488d..e29ee40adcee8d9fb4209af65e44a6314366d2c8 100644 (file)
@@ -17,12 +17,11 @@ from collections import deque
 # with the multiprocessing module, which doesn't provide the old
 # Java inspired names.
 
-
-# Rename some stuff so "from threading import *" is safe
 __all__ = ['active_count', 'Condition', 'current_thread', 'enumerate', 'Event',
-           'Lock', 'RLock', 'Semaphore', 'BoundedSemaphore', 'Thread',
+           'Lock', 'RLock', 'Semaphore', 'BoundedSemaphore', 'Thread', 'Barrier',
            'Timer', 'setprofile', 'settrace', 'local', 'stack_size']
 
+# Rename some stuff so "from threading import *" is safe
 _start_new_thread = _thread.start_new_thread
 _allocate_lock = _thread.allocate_lock
 _get_ident = _thread.get_ident