diff -r 99be11bd4acc Doc/library/multiprocessing.rst --- a/Doc/library/multiprocessing.rst Tue Mar 13 14:34:04 2012 -0700 +++ b/Doc/library/multiprocessing.rst Wed Mar 14 15:23:01 2012 -0300 @@ -1719,6 +1719,11 @@ Wait for the worker processes to exit. One must call :meth:`close` or :meth:`terminate` before using :meth:`join`. + .. method:: is_alive + + Return whether any process is alive in the Pool. One must call + :meth:`close` or :meth:`terminate` before using :meth:`is_alive`. + .. class:: AsyncResult diff -r 99be11bd4acc Lib/multiprocessing/pool.py --- a/Lib/multiprocessing/pool.py Tue Mar 13 14:34:04 2012 -0700 +++ b/Lib/multiprocessing/pool.py Wed Mar 14 15:23:01 2012 -0300 @@ -325,6 +325,14 @@ assert self._state == RUN return self._map_async(func, iterable, mapstar, chunksize) + def is_alive(self): + ''' + Return whether there are any active processes in a closed or + terminated Pool. + ''' + assert self._state in (CLOSE, TERMINATE) + return any(p.is_alive() for p in self._pool) + def _map_async(self, func, iterable, mapper, chunksize=None, callback=None, error_callback=None): ''' diff -r 99be11bd4acc Lib/test/test_multiprocessing.py --- a/Lib/test/test_multiprocessing.py Tue Mar 13 14:34:04 2012 -0700 +++ b/Lib/test/test_multiprocessing.py Wed Mar 14 15:23:01 2012 -0300 @@ -1245,6 +1245,25 @@ join() self.assertLess(join.elapsed, 0.5) + def test_is_alive(self): + p = multiprocessing.Pool() + p.apply_async(sqr, (10, 60)) + p.close() + + self.assertTrue(p.is_alive()) + + p.terminate() + p.join() + + self.assertFalse(p.is_alive()) + + p = multiprocessing.Pool() + p.apply_async(mul) + p.close() + p.join() + + self.assertFalse(p.is_alive()) + def raising(): raise KeyError("key")