I'm doing some multiprocessing python scripts using multiprocessing.Pool
. These scripts look like the following:
from multiprocessing import Pool
def f(x):
return x*x
if __name__ == '__main__':
with Pool(processes=4) as pool: # start 4 worker processes
print(pool.map(f, range(10))) # prints "[0, 1, 4,..., 81]"
When running this with Python 3.4, everything is fine. However, when using Python 2.6 or 3.1 I get this error:
AttributeError: 'Pool' object has no attribute '__exit__'
Using Python 2.7 or 3.2, the error is essentially the same:
AttributeError: __exit__
Why does this happen and how can I circumvent this?
The documentation says that multiprocessing.pool
supports the context management protocol (with
statements) in Python version 3.3 and above.
New in version 3.3: Pool objects now support the context management protocol – see Context Manager Types.
__enter__()
returns the pool object, and__exit__()
callsterminate()
.
So you either need a newer version of Python, or use one of the two following possibilities changing your code (tested with Python versions 2.6, 2.7, 3.1, 3.2):
rewrite your code like this to eliminate the with
statement:
from multiprocessing import Pool
def f(x):
return x*x
if __name__ == '__main__':
pool = Pool(processes=4) # start 4 worker processes
print(pool.map(f, range(10))) # prints "[0, 1, 4,..., 81]"
pool.terminate()
as pointed out in the comments, use contextlib.closing()
:
from multiprocessing import Pool
import contextlib
def f(x):
return x*x
if __name__ == '__main__':
with contextlib.closing(Pool(processes=4)) as pool:
print(pool.map(f, range(10)))