Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 3730a17

Browse files
committed
Issue #14059: Implement multiprocessing.Barrier
1 parent a6bc4b4 commit 3730a17

7 files changed

Lines changed: 426 additions & 12 deletions

File tree

Doc/library/multiprocessing.rst

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -226,11 +226,11 @@ However, if you really do need to use some shared data then
226226
holds Python objects and allows other processes to manipulate them using
227227
proxies.
228228

229-
A manager returned by :func:`Manager` will support types :class:`list`,
230-
:class:`dict`, :class:`Namespace`, :class:`Lock`, :class:`RLock`,
231-
:class:`Semaphore`, :class:`BoundedSemaphore`, :class:`Condition`,
232-
:class:`Event`, :class:`Queue`, :class:`Value` and :class:`Array`. For
233-
example, ::
229+
A manager returned by :func:`Manager` will support types
230+
:class:`list`, :class:`dict`, :class:`Namespace`, :class:`Lock`,
231+
:class:`RLock`, :class:`Semaphore`, :class:`BoundedSemaphore`,
232+
:class:`Condition`, :class:`Event`, :class:`Barrier`,
233+
:class:`Queue`, :class:`Value` and :class:`Array`. For example, ::
234234

235235
from multiprocessing import Process, Manager
236236

@@ -885,6 +885,12 @@ program as they are in a multithreaded program. See the documentation for
885885
Note that one can also create synchronization primitives by using a manager
886886
object -- see :ref:`multiprocessing-managers`.
887887

888+
.. class:: Barrier(parties[, action[, timeout]])
889+
890+
A barrier object: a clone of :class:`threading.Barrier`.
891+
892+
.. versionadded:: 3.3
893+
888894
.. class:: BoundedSemaphore([value])
889895

890896
A bounded semaphore object: a clone of :class:`threading.BoundedSemaphore`.
@@ -1280,6 +1286,13 @@ their parent process exits. The manager classes are defined in the
12801286

12811287
It also supports creation of shared lists and dictionaries.
12821288

1289+
.. method:: Barrier(parties[, action[, timeout]])
1290+
1291+
Create a shared :class:`threading.Barrier` object and return a
1292+
proxy for it.
1293+
1294+
.. versionadded:: 3.3
1295+
12831296
.. method:: BoundedSemaphore([value])
12841297

12851298
Create a shared :class:`threading.BoundedSemaphore` object and return a

Lib/multiprocessing/__init__.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@
2323
'Manager', 'Pipe', 'cpu_count', 'log_to_stderr', 'get_logger',
2424
'allow_connection_pickling', 'BufferTooShort', 'TimeoutError',
2525
'Lock', 'RLock', 'Semaphore', 'BoundedSemaphore', 'Condition',
26-
'Event', 'Queue', 'SimpleQueue', 'JoinableQueue', 'Pool', 'Value', 'Array',
27-
'RawValue', 'RawArray', 'SUBDEBUG', 'SUBWARNING',
26+
'Event', 'Barrier', 'Queue', 'SimpleQueue', 'JoinableQueue', 'Pool',
27+
'Value', 'Array', 'RawValue', 'RawArray', 'SUBDEBUG', 'SUBWARNING',
2828
]
2929

3030
__author__ = 'R. Oudkerk ([email protected])'
@@ -186,6 +186,13 @@ def Event():
186186
from multiprocessing.synchronize import Event
187187
return Event()
188188

189+
def Barrier(parties, action=None, timeout=None):
190+
'''
191+
Returns a barrier object
192+
'''
193+
from multiprocessing.synchronize import Barrier
194+
return Barrier(parties, action, timeout)
195+
189196
def Queue(maxsize=0):
190197
'''
191198
Returns a queue object

Lib/multiprocessing/dummy/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
__all__ = [
3636
'Process', 'current_process', 'active_children', 'freeze_support',
3737
'Lock', 'RLock', 'Semaphore', 'BoundedSemaphore', 'Condition',
38-
'Event', 'Queue', 'Manager', 'Pipe', 'Pool', 'JoinableQueue'
38+
'Event', 'Barrier', 'Queue', 'Manager', 'Pipe', 'Pool', 'JoinableQueue'
3939
]
4040

4141
#
@@ -49,7 +49,7 @@
4949

5050
from multiprocessing.dummy.connection import Pipe
5151
from threading import Lock, RLock, Semaphore, BoundedSemaphore
52-
from threading import Event, Condition
52+
from threading import Event, Condition, Barrier
5353
from queue import Queue
5454

5555
#

Lib/multiprocessing/managers.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -993,6 +993,26 @@ def clear(self):
993993
def wait(self, timeout=None):
994994
return self._callmethod('wait', (timeout,))
995995

996+
997+
class BarrierProxy(BaseProxy):
998+
_exposed_ = ('__getattribute__', 'wait', 'abort', 'reset')
999+
def wait(self, timeout=None):
1000+
return self._callmethod('wait', (timeout,))
1001+
def abort(self):
1002+
return self._callmethod('abort')
1003+
def reset(self):
1004+
return self._callmethod('reset')
1005+
@property
1006+
def parties(self):
1007+
return self._callmethod('__getattribute__', ('parties',))
1008+
@property
1009+
def n_waiting(self):
1010+
return self._callmethod('__getattribute__', ('n_waiting',))
1011+
@property
1012+
def broken(self):
1013+
return self._callmethod('__getattribute__', ('broken',))
1014+
1015+
9961016
class NamespaceProxy(BaseProxy):
9971017
_exposed_ = ('__getattribute__', '__setattr__', '__delattr__')
9981018
def __getattr__(self, key):
@@ -1084,6 +1104,7 @@ class SyncManager(BaseManager):
10841104
SyncManager.register('BoundedSemaphore', threading.BoundedSemaphore,
10851105
AcquirerProxy)
10861106
SyncManager.register('Condition', threading.Condition, ConditionProxy)
1107+
SyncManager.register('Barrier', threading.Barrier, BarrierProxy)
10871108
SyncManager.register('Pool', Pool, PoolProxy)
10881109
SyncManager.register('list', list, ListProxy)
10891110
SyncManager.register('dict', dict, DictProxy)

Lib/multiprocessing/synchronize.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,3 +333,43 @@ def wait(self, timeout=None):
333333
return False
334334
finally:
335335
self._cond.release()
336+
337+
#
338+
# Barrier
339+
#
340+
341+
class Barrier(threading.Barrier):
342+
343+
def __init__(self, parties, action=None, timeout=None):
344+
import struct
345+
from multiprocessing.heap import BufferWrapper
346+
wrapper = BufferWrapper(struct.calcsize('i') * 2)
347+
cond = Condition()
348+
self.__setstate__((parties, action, timeout, cond, wrapper))
349+
self._state = 0
350+
self._count = 0
351+
352+
def __setstate__(self, state):
353+
(self._parties, self._action, self._timeout,
354+
self._cond, self._wrapper) = state
355+
self._array = self._wrapper.create_memoryview().cast('i')
356+
357+
def __getstate__(self):
358+
return (self._parties, self._action, self._timeout,
359+
self._cond, self._wrapper)
360+
361+
@property
362+
def _state(self):
363+
return self._array[0]
364+
365+
@_state.setter
366+
def _state(self, value):
367+
self._array[0] = value
368+
369+
@property
370+
def _count(self):
371+
return self._array[1]
372+
373+
@_count.setter
374+
def _count(self, value):
375+
self._array[1] = value

0 commit comments

Comments
 (0)