20

データを取得してモジュールB、C、Dなどに送信して分析し、それらの結果を結合することにより、基本的なマップ/リデュースを行うモジュールAがあります。

しかし、モジュールB、C、Dなどはそれ自体でマルチプロセッシングプールを作成できないようです。

AssertionError: daemonic processes are not allowed to have children

これらのジョブを他の方法で並列化することは可能ですか?

わかりやすくするために、(確かに悪い) 赤ちゃんの例を示します。(私は通常、試したりキャッチしたりしますが、要点はわかります)。

A.py:

  import B
  from multiprocessing import Pool

  def main():
    p = Pool()
    results = p.map(B.foo,range(10))
    p.close()
    p.join()
    return results


B.py:
  
  from multiprocessing import Pool

  def foo(x):
    p = Pool()
    results = p.map(str,x)
    p.close()
    p.join()
    return results
4

1 に答える 1

27

プールの中にプールを作ることは可能ですか?

はい、可能ですが、ゾンビの軍隊を育てたいのでない限り、それは良い考えではないかもしれません. 非デーモンの Python プロセス プールから? :

import multiprocessing.pool
from contextlib import closing
from functools import partial

class NoDaemonProcess(multiprocessing.Process):
    # make 'daemon' attribute always return False
    def _get_daemon(self):
        return False
    def _set_daemon(self, value):
        pass
    daemon = property(_get_daemon, _set_daemon)

# We sub-class multiprocessing.pool.Pool instead of multiprocessing.Pool
# because the latter is only a wrapper function, not a proper class.
class Pool(multiprocessing.pool.Pool):
    Process = NoDaemonProcess

def foo(x, depth=0):
    if depth == 0:
        return x
    else:
        with closing(Pool()) as p:
            return p.map(partial(foo, depth=depth-1), range(x + 1))

if __name__ == "__main__":
    from pprint import pprint
    pprint(foo(10, depth=2))

出力

[[0],
 [0, 1],
 [0, 1, 2],
 [0, 1, 2, 3],
 [0, 1, 2, 3, 4],
 [0, 1, 2, 3, 4, 5],
 [0, 1, 2, 3, 4, 5, 6],
 [0, 1, 2, 3, 4, 5, 6, 7],
 [0, 1, 2, 3, 4, 5, 6, 7, 8],
 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]]

concurrent.futuresデフォルトでサポートしています:

# $ pip install futures # on Python 2
from concurrent.futures import ProcessPoolExecutor as Pool
from functools import partial

def foo(x, depth=0):
    if depth == 0:
        return x
    else:
        with Pool() as p:
            return list(p.map(partial(foo, depth=depth-1), range(x + 1)))

if __name__ == "__main__":
    from pprint import pprint
    pprint(foo(10, depth=2))

同じ出力が生成されます。

これらのジョブを他の方法で並列化することは可能ですか?

はい。たとえばcelery、複雑なワークフローを作成する方法を見てください。

于 2013-06-21T06:34:53.747 に答える