| OLD | NEW |
| (Empty) | |
| 1 # Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. |
| 4 |
| 5 """Convenience functions for code calling the multiprocessing module.""" |
| 6 |
| 7 import contextlib |
| 8 import multiprocessing |
| 9 |
| 10 |
| 11 @contextlib.contextmanager |
| 12 def MultiPool(processes): |
| 13 """Manages a multiprocessing.Pool making sure to close the pool when done. |
| 14 |
| 15 This will also call pool.terminate() when an exception is raised (and |
| 16 re-raised the exception to the calling procedure can handle it). |
| 17 |
| 18 If you plan on using a multiprocess pool, take a look at |
| 19 http://bugs.python.org/issue12157 and |
| 20 http://stackoverflow.com/a/1408476/3984761. |
| 21 """ |
| 22 try: |
| 23 pool = multiprocessing.Pool(processes=processes) |
| 24 yield pool |
| 25 pool.close() |
| 26 except: |
| 27 pool.terminate() |
| 28 raise |
| 29 finally: |
| 30 pool.join() |
| 31 |
| 32 |
| 33 def safe_map(func, args, processes): # pragma: no cover |
| 34 """Executes a function over multiple sets of arguments in parallel. |
| 35 |
| 36 This works around two gotchas easily encountered when using |
| 37 multiprocessing.Pool.map_async(). Specifically, that map_async() can hang if |
| 38 the arguent count is an empty list, and that KeyboardInterrupts are not |
| 39 handled properly. |
| 40 |
| 41 func must be a real, top-level function (cannot be a nested function or |
| 42 lambda, see http://stackoverflow.com/q/8804830/3984761). It should take |
| 43 a single argument. |
| 44 |
| 45 args is an iterable of arguments over which repeated func calls are made. |
| 46 |
| 47 processes is the number of processes to use for execution. |
| 48 """ |
| 49 |
| 50 # Prevent map from hanging, see http://bugs.python.org/issue12157. |
| 51 if not args: |
| 52 return [] |
| 53 |
| 54 with MultiPool(processes) as pool: |
| 55 # This strange invocation is so ctrl-c can interrupt the map_async. See |
| 56 # http://stackoverflow.com/a/1408476/3984761 for details. |
| 57 return pool.map_async(func, args).get(9999999) |
| OLD | NEW |