Commit 3730a17a authored by Richard Oudkerk's avatar Richard Oudkerk

Issue #14059: Implement multiprocessing.Barrier

parent a6bc4b4c
...@@ -226,11 +226,11 @@ However, if you really do need to use some shared data then ...@@ -226,11 +226,11 @@ However, if you really do need to use some shared data then
holds Python objects and allows other processes to manipulate them using holds Python objects and allows other processes to manipulate them using
proxies. proxies.
A manager returned by :func:`Manager` will support types :class:`list`, A manager returned by :func:`Manager` will support types
:class:`dict`, :class:`Namespace`, :class:`Lock`, :class:`RLock`, :class:`list`, :class:`dict`, :class:`Namespace`, :class:`Lock`,
:class:`Semaphore`, :class:`BoundedSemaphore`, :class:`Condition`, :class:`RLock`, :class:`Semaphore`, :class:`BoundedSemaphore`,
:class:`Event`, :class:`Queue`, :class:`Value` and :class:`Array`. For :class:`Condition`, :class:`Event`, :class:`Barrier`,
example, :: :class:`Queue`, :class:`Value` and :class:`Array`. For example, ::
from multiprocessing import Process, Manager from multiprocessing import Process, Manager
...@@ -885,6 +885,12 @@ program as they are in a multithreaded program. See the documentation for ...@@ -885,6 +885,12 @@ program as they are in a multithreaded program. See the documentation for
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`.
.. class:: Barrier(parties[, action[, timeout]])
A barrier object: a clone of :class:`threading.Barrier`.
.. versionadded:: 3.3
.. class:: BoundedSemaphore([value]) .. class:: BoundedSemaphore([value])
A bounded semaphore object: a clone of :class:`threading.BoundedSemaphore`. 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 ...@@ -1280,6 +1286,13 @@ their parent process exits. The manager classes are defined in the
It also supports creation of shared lists and dictionaries. It also supports creation of shared lists and dictionaries.
.. method:: Barrier(parties[, action[, timeout]])
Create a shared :class:`threading.Barrier` object and return a
proxy for it.
.. versionadded:: 3.3
.. method:: BoundedSemaphore([value]) .. method:: BoundedSemaphore([value])
Create a shared :class:`threading.BoundedSemaphore` object and return a Create a shared :class:`threading.BoundedSemaphore` object and return a
......
...@@ -23,8 +23,8 @@ __all__ = [ ...@@ -23,8 +23,8 @@ __all__ = [
'Manager', 'Pipe', 'cpu_count', 'log_to_stderr', 'get_logger', 'Manager', 'Pipe', 'cpu_count', 'log_to_stderr', 'get_logger',
'allow_connection_pickling', 'BufferTooShort', 'TimeoutError', 'allow_connection_pickling', 'BufferTooShort', 'TimeoutError',
'Lock', 'RLock', 'Semaphore', 'BoundedSemaphore', 'Condition', 'Lock', 'RLock', 'Semaphore', 'BoundedSemaphore', 'Condition',
'Event', 'Queue', 'SimpleQueue', 'JoinableQueue', 'Pool', 'Value', 'Array', 'Event', 'Barrier', 'Queue', 'SimpleQueue', 'JoinableQueue', 'Pool',
'RawValue', 'RawArray', 'SUBDEBUG', 'SUBWARNING', 'Value', 'Array', 'RawValue', 'RawArray', 'SUBDEBUG', 'SUBWARNING',
] ]
__author__ = 'R. Oudkerk (r.m.oudkerk@gmail.com)' __author__ = 'R. Oudkerk (r.m.oudkerk@gmail.com)'
...@@ -186,6 +186,13 @@ def Event(): ...@@ -186,6 +186,13 @@ def Event():
from multiprocessing.synchronize import Event from multiprocessing.synchronize import Event
return Event() return Event()
def Barrier(parties, action=None, timeout=None):
'''
Returns a barrier object
'''
from multiprocessing.synchronize import Barrier
return Barrier(parties, action, timeout)
def Queue(maxsize=0): def Queue(maxsize=0):
''' '''
Returns a queue object Returns a queue object
......
...@@ -35,7 +35,7 @@ ...@@ -35,7 +35,7 @@
__all__ = [ __all__ = [
'Process', 'current_process', 'active_children', 'freeze_support', 'Process', 'current_process', 'active_children', 'freeze_support',
'Lock', 'RLock', 'Semaphore', 'BoundedSemaphore', 'Condition', 'Lock', 'RLock', 'Semaphore', 'BoundedSemaphore', 'Condition',
'Event', 'Queue', 'Manager', 'Pipe', 'Pool', 'JoinableQueue' 'Event', 'Barrier', 'Queue', 'Manager', 'Pipe', 'Pool', 'JoinableQueue'
] ]
# #
...@@ -49,7 +49,7 @@ import array ...@@ -49,7 +49,7 @@ import array
from multiprocessing.dummy.connection import Pipe from multiprocessing.dummy.connection import Pipe
from threading import Lock, RLock, Semaphore, BoundedSemaphore from threading import Lock, RLock, Semaphore, BoundedSemaphore
from threading import Event, Condition from threading import Event, Condition, Barrier
from queue import Queue from queue import Queue
# #
......
...@@ -993,6 +993,26 @@ class EventProxy(BaseProxy): ...@@ -993,6 +993,26 @@ class EventProxy(BaseProxy):
def wait(self, timeout=None): def wait(self, timeout=None):
return self._callmethod('wait', (timeout,)) return self._callmethod('wait', (timeout,))
class BarrierProxy(BaseProxy):
_exposed_ = ('__getattribute__', 'wait', 'abort', 'reset')
def wait(self, timeout=None):
return self._callmethod('wait', (timeout,))
def abort(self):
return self._callmethod('abort')
def reset(self):
return self._callmethod('reset')
@property
def parties(self):
return self._callmethod('__getattribute__', ('parties',))
@property
def n_waiting(self):
return self._callmethod('__getattribute__', ('n_waiting',))
@property
def broken(self):
return self._callmethod('__getattribute__', ('broken',))
class NamespaceProxy(BaseProxy): class NamespaceProxy(BaseProxy):
_exposed_ = ('__getattribute__', '__setattr__', '__delattr__') _exposed_ = ('__getattribute__', '__setattr__', '__delattr__')
def __getattr__(self, key): def __getattr__(self, key):
...@@ -1084,6 +1104,7 @@ SyncManager.register('Semaphore', threading.Semaphore, AcquirerProxy) ...@@ -1084,6 +1104,7 @@ SyncManager.register('Semaphore', threading.Semaphore, AcquirerProxy)
SyncManager.register('BoundedSemaphore', threading.BoundedSemaphore, SyncManager.register('BoundedSemaphore', threading.BoundedSemaphore,
AcquirerProxy) AcquirerProxy)
SyncManager.register('Condition', threading.Condition, ConditionProxy) SyncManager.register('Condition', threading.Condition, ConditionProxy)
SyncManager.register('Barrier', threading.Barrier, BarrierProxy)
SyncManager.register('Pool', Pool, PoolProxy) SyncManager.register('Pool', Pool, PoolProxy)
SyncManager.register('list', list, ListProxy) SyncManager.register('list', list, ListProxy)
SyncManager.register('dict', dict, DictProxy) SyncManager.register('dict', dict, DictProxy)
......
...@@ -333,3 +333,43 @@ class Event(object): ...@@ -333,3 +333,43 @@ class Event(object):
return False return False
finally: finally:
self._cond.release() self._cond.release()
#
# Barrier
#
class Barrier(threading.Barrier):
def __init__(self, parties, action=None, timeout=None):
import struct
from multiprocessing.heap import BufferWrapper
wrapper = BufferWrapper(struct.calcsize('i') * 2)
cond = Condition()
self.__setstate__((parties, action, timeout, cond, wrapper))
self._state = 0
self._count = 0
def __setstate__(self, state):
(self._parties, self._action, self._timeout,
self._cond, self._wrapper) = state
self._array = self._wrapper.create_memoryview().cast('i')
def __getstate__(self):
return (self._parties, self._action, self._timeout,
self._cond, self._wrapper)
@property
def _state(self):
return self._array[0]
@_state.setter
def _state(self, value):
self._array[0] = value
@property
def _count(self):
return self._array[1]
@_count.setter
def _count(self, value):
self._array[1] = value
This diff is collapsed.
...@@ -21,6 +21,8 @@ Core and Builtins ...@@ -21,6 +21,8 @@ Core and Builtins
Library Library
------- -------
- Issue #14059: Implement multiprocessing.Barrier.
- Issue #15061: The inappropriately named hmac.secure_compare has been - Issue #15061: The inappropriately named hmac.secure_compare has been
renamed to hmac.compare_digest, restricted to operating on bytes inputs renamed to hmac.compare_digest, restricted to operating on bytes inputs
only and had its documentation updated to more accurately reflect both its only and had its documentation updated to more accurately reflect both its
......
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