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

Skip to content

Commit de911b2

Browse files
committed
Issue #12708: Add starmap() and starmap_async() methods (similar to itertools.starmap()) to multiprocessing.Pool.
Patch by Hynek Schlawack.
1 parent 12f65d1 commit de911b2

6 files changed

Lines changed: 72 additions & 3 deletions

File tree

Doc/library/multiprocessing.rst

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1669,6 +1669,24 @@ with the :class:`Pool` class.
16691669
returned iterator should be considered arbitrary. (Only when there is
16701670
only one worker process is the order guaranteed to be "correct".)
16711671

1672+
.. method:: starmap(func, iterable[, chunksize])
1673+
1674+
Like :meth:`map` except that the elements of the `iterable` are expected
1675+
to be iterables that are unpacked as arguments.
1676+
1677+
Hence an `iterable` of `[(1,2), (3, 4)]` results in `[func(1,2),
1678+
func(3,4)]`.
1679+
1680+
.. versionadded:: 3.3
1681+
1682+
.. method:: starmap_async(func, iterable[, chunksize[, callback[, error_back]]])
1683+
1684+
A combination of :meth:`starmap` and :meth:`map_async` that iterates over
1685+
`iterable` of iterables and calls `func` with the iterables unpacked.
1686+
Returns a result object.
1687+
1688+
.. versionadded:: 3.3
1689+
16721690
.. method:: close()
16731691

16741692
Prevents any more tasks from being submitted to the pool. Once all the

Lib/multiprocessing/managers.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1066,11 +1066,12 @@ def __imul__(self, value):
10661066

10671067
PoolProxy = MakeProxyType('PoolProxy', (
10681068
'apply', 'apply_async', 'close', 'imap', 'imap_unordered', 'join',
1069-
'map', 'map_async', 'terminate'
1069+
'map', 'map_async', 'starmap', 'starmap_async', 'terminate'
10701070
))
10711071
PoolProxy._method_to_typeid_ = {
10721072
'apply_async': 'AsyncResult',
10731073
'map_async': 'AsyncResult',
1074+
'starmap_async': 'AsyncResult',
10741075
'imap': 'Iterator',
10751076
'imap_unordered': 'Iterator'
10761077
}

Lib/multiprocessing/pool.py

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,9 @@
6464
def mapstar(args):
6565
return list(map(*args))
6666

67+
def starmapstar(args):
68+
return list(itertools.starmap(args[0], args[1]))
69+
6770
#
6871
# Code run by worker processes
6972
#
@@ -248,7 +251,25 @@ def map(self, func, iterable, chunksize=None):
248251
in a list that is returned.
249252
'''
250253
assert self._state == RUN
251-
return self.map_async(func, iterable, chunksize).get()
254+
return self._map_async(func, iterable, mapstar, chunksize).get()
255+
256+
def starmap(self, func, iterable, chunksize=None):
257+
'''
258+
Like `map()` method but the elements of the `iterable` are expected to
259+
be iterables as well and will be unpacked as arguments. Hence
260+
`func` and (a, b) becomes func(a, b).
261+
'''
262+
assert self._state == RUN
263+
return self._map_async(func, iterable, starmapstar, chunksize).get()
264+
265+
def starmap_async(self, func, iterable, chunksize=None, callback=None,
266+
error_callback=None):
267+
'''
268+
Asynchronous version of `starmap()` method.
269+
'''
270+
assert self._state == RUN
271+
return self._map_async(func, iterable, starmapstar, chunksize,
272+
callback, error_callback)
252273

253274
def imap(self, func, iterable, chunksize=1):
254275
'''
@@ -302,6 +323,13 @@ def map_async(self, func, iterable, chunksize=None, callback=None,
302323
Asynchronous version of `map()` method.
303324
'''
304325
assert self._state == RUN
326+
return self._map_async(func, iterable, mapstar, chunksize)
327+
328+
def _map_async(self, func, iterable, mapper, chunksize=None, callback=None,
329+
error_callback=None):
330+
'''
331+
Helper function to implement map, starmap and their async counterparts.
332+
'''
305333
if not hasattr(iterable, '__len__'):
306334
iterable = list(iterable)
307335

@@ -315,7 +343,7 @@ def map_async(self, func, iterable, chunksize=None, callback=None,
315343
task_batches = Pool._get_tasks(func, iterable, chunksize)
316344
result = MapResult(self._cache, chunksize, len(iterable), callback,
317345
error_callback=error_callback)
318-
self._taskqueue.put((((result._job, i, mapstar, (x,), {})
346+
self._taskqueue.put((((result._job, i, mapper, (x,), {})
319347
for i, x in enumerate(task_batches)), None))
320348
return result
321349

Lib/test/test_multiprocessing.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import queue as pyqueue
99
import time
1010
import io
11+
import itertools
1112
import sys
1213
import os
1314
import gc
@@ -1125,6 +1126,9 @@ def sqr(x, wait=0.0):
11251126
time.sleep(wait)
11261127
return x*x
11271128

1129+
def mul(x, y):
1130+
return x*y
1131+
11281132
class _TestPool(BaseTestCase):
11291133

11301134
def test_apply(self):
@@ -1138,6 +1142,20 @@ def test_map(self):
11381142
self.assertEqual(pmap(sqr, list(range(100)), chunksize=20),
11391143
list(map(sqr, list(range(100)))))
11401144

1145+
def test_starmap(self):
1146+
psmap = self.pool.starmap
1147+
tuples = list(zip(range(10), range(9,-1, -1)))
1148+
self.assertEqual(psmap(mul, tuples),
1149+
list(itertools.starmap(mul, tuples)))
1150+
tuples = list(zip(range(100), range(99,-1, -1)))
1151+
self.assertEqual(psmap(mul, tuples, chunksize=20),
1152+
list(itertools.starmap(mul, tuples)))
1153+
1154+
def test_starmap_async(self):
1155+
tuples = list(zip(range(100), range(99,-1, -1)))
1156+
self.assertEqual(self.pool.starmap_async(mul, tuples).get(),
1157+
list(itertools.starmap(mul, tuples)))
1158+
11411159
def test_map_chunksize(self):
11421160
try:
11431161
self.pool.map_async(sqr, [], chunksize=1).get(timeout=TIMEOUT1)

Misc/ACKS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -878,6 +878,7 @@ Michael Scharf
878878
Andreas Schawo
879879
Neil Schemenauer
880880
David Scherer
881+
Hynek Schlawack
881882
Bob Schmertz
882883
Gregor Schmid
883884
Ralf Schmitt

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,9 @@ Core and Builtins
419419
Library
420420
-------
421421

422+
- Issue #12708: Add starmap() and starmap_async() methods (similar to
423+
itertools.starmap()) to multiprocessing.Pool. Patch by Hynek Schlawack.
424+
422425
- Issue #1785: Fix inspect and pydoc with misbehaving descriptors.
423426

424427
- Issue #13637: "a2b" functions in the binascii module now accept ASCII-only

0 commit comments

Comments
 (0)