【Python】multiprocessing の pool.Pool() で『Exception escaped from start_client』が出るときは set_start_method() を使う

Pythonで並列処理をするときに、multiprocessingpool.Pool() でエラーが出ました。

その解決方法です。

『Windows 7』で実行していたときは問題なく動いていたのですが、『Linux Mint』で実行したときに、『Exception escaped from start_client』とか、『RuntimeError: already started』といったエラーが出ました。

そして最後に、『Terminated』と表示されて、プログラムが止まりました。

エラーは『デバッグモード』で動かしたときにだけ、発生しました。

結論ですが、同じく multiprocessing の中にある set_start_method() を使ったところ、エラーが出なくなりました。

そのときのコード例を紹介します。

この set_start_method() ですが、Python の公式マニュアルによると、if __name__ == "__main__":節内せつないに書きましょう、とのことでした。
スポンサーリンク

問題のコード ⇒ pool.Pool() でエラー

multiprocessingpool.Pool() でエラーが出た時のコードです。

エラーですが、with 文のところで発生していました。

with 文の as 節で受け取った p で何かをする前に、エラーが発生していました。

from multiprocessing import pool

def main():
    with pool.Pool(processes=1) as p: # ← ここでエラー発生
        print('ok')
    return

if __name__ == "__main__":
    main()

エラーが出たときの実行環境は、Linux Mint 19.2、Python 3.6.8 です。

Virtual Box 6.0 の中で実行しました。

Visual Studio Code を使って、デバッグモードで実行したときにだけ、エラーが出ました。たとえば、『デバッグの開始』や『F5キー』で実行したときに、エラーが出ました。

一方で、『デバッグなしで開始』や『ターミナルで Python ファイルを実行』で実行したときは、エラー無く実行できました。

Windows 7 で実行したときは、デバッグモードでも、そうでなくても、エラーは出ませんでした。

実行結果 (Exception escaped from start_client)

エラーが出た時の実行結果です。

E00000.257: Exception escaped from start_client

  Traceback (most recent call last):
    File "/home/*/extensions/ms-python.python-2019.9.34911/pythonFiles/lib/python/ptvsd/log.py", line 110, in g
      return f(*args, **kwargs)
    File "/home/*/extensions/ms-python.python-2019.9.34911/pythonFiles/lib/python/ptvsd/pydevd_hooks.py", line 74, in start_client
      sock, start_session = daemon.start_client((host, port))
    File "/home/*/extensions/ms-python.python-2019.9.34911/pythonFiles/lib/python/ptvsd/daemon.py", line 214, in start_client
      with self.started():
    File "/usr/lib/python3.6/contextlib.py", line 81, in __enter__
      return next(self.gen)
    File "/home/*/extensions/ms-python.python-2019.9.34911/pythonFiles/lib/python/ptvsd/daemon.py", line 110, in started
      self.start()
    File "/home/*/extensions/ms-python.python-2019.9.34911/pythonFiles/lib/python/ptvsd/daemon.py", line 145, in start
      raise RuntimeError('already started')
  RuntimeError: already started

Traceback (most recent call last):
Terminated

Exception escaped from start_client や、RuntimeError: already started といった内容のエラーが表示されています。

※『E00000.257:』のところの数字は、実行するたびに変わりました。

スポンサーリンク

解決したコード ⇒ set_start_method() を追加

解決方法ですが、マルチプロセッシング (multiprocessing) のパッケージから、セットスタートメソッド (set_start_method) をインポートして使いました。

自分の場合は、これで解決しました。

デバッグモードでプログラムを実行しても、エラーが出なくなりました。

解決したときのコードです。

from multiprocessing import pool
from multiprocessing import set_start_method

def main():
    with pool.Pool(processes=1) as p:
        print('ok')
    return

if __name__ == "__main__":
    # set_start_method() は、ここに書いてくださいとのこと。
    set_start_method('spawn', True)
    main()

公式マニュアルの場所です。

multiprocessing プロセスベースの並列処理

ところで、set_start_method() を書く場所ですが、上記の公式マニュアルに指示がありました。

if __name__ == "__main__":節内せつないに書きましょうとのことでした。

multiprocessing.set_start_method(method)
子プロセスの開始方式を指定します。method には 'fork''spawn' あるいは 'forkserver' を指定できます。

これは一度しか呼び出すことができず、その場所もメインモジュールの if __name__ == '__main__' 節内で保護された状態でなければなりません。

バージョン 3.4 で追加.

multiprocessing — プロセスベースの並列処理 — Python 3.7.4 ドキュメント

実行結果 OK

解決したコードで、プログラムを実行した結果です。

Linux Mint ⇒ Visual Studio Code ⇒『デバッグ開始』で実行しました。

ok

print() で表示した ok だけが出ました。

set_start_method() を使ったことで、デバッグモードで実行しても、エラーが出なくなりました。

タイトルとURLをコピーしました