Up

Poolの使用におけるinputの位置によるトラブル

 

マルチプロセッシングをPoolによって行う場合、入力関数inputの位置は重要である。入力関数inputが条件文if __name__ == __main__’のsuite内(ブロック内)に置かれておればよいが、その前にあると暴走する。簡単な例を示す。

リスト1のスクリプトは、マルチプロセッシングにより2つのフォームが3秒間表示されるものである。

リスト1

from tkinter import *

from multiprocessing.pool import Pool

import time

 

def funcs( params ):

    root = Tk()

    canvas = Canvas(root, bg = '#ffffff', width = 400, height = 300)

    canvas.pack()

    canvas.create_text(200, 150, text = 'I am Proc-' + params, font = ('Gothic', 32), tags = 'mytext')

    canvas.update()

    time.sleep(3)

    root.destroy()

    return

 

if __name__ == '__main__':

    params = ['A', 'B']

    print('Are you ready ?')

    input('If ready, press Enter-key')

    pool = Pool()

    Results = pool.map(funcs, params)

 

リスト1を実行すると、まず、図1のようにEnterキーを押すことが求められる。

図1

 

Enterキーを押すと、Poolによるマルチプロセッシングが始まり、2つのフォームが表示される(図2)。

図2

 

3秒立つと図2のフォームは消え、プログラムの実行終了となる。

 

いま、input関数の位置を条件文if __name__ == __main__’のブロックの外に置いて、リスト2のように書き変える。

リスト2

from tkinter import *

from multiprocessing.pool import Pool

import time

 

def funcs( params ):

    root = Tk()

    canvas = Canvas(root, bg = '#ffffff', width = 400, height = 300)

    canvas.pack()

    canvas.create_text(200, 150, text = 'I am Proc-' + params, font = ('Gothic', 32), tags = 'mytext')

    canvas.update()

    time.sleep(3)

    root.destroy()

    return

 

print('Are you ready ?')

input('If ready, press Enter-key')

if __name__ == '__main__':

    params = ['A', 'B']

    pool = Pool()

    Results = pool.map(funcs, params)

 

リスト2の場合は、図1の画面においてEnterキーを押しても図2のフォームはいつまで待っても表示されない。関数inputの実行は、条件文if __name__ == __main__’のブロック内で行われる必要がある。

リスト2を実行したときに、Enterキーを押していつまでもフォームが表示されない状態のときは、メニュ項目「Shell|Restart Shell」を選べば終了できる(図3)。

図3

 

関数inputif __name__ == '__main__'のブロックの外で実行したときに起こる問題は、実行環境に依存している。端末Windows PowerShellにおいてリスト2のスクリプトを実行すると図4のようになる。

図4

 

関数printinputによる出力が何回か行われ、Enterキーを数回押せば図2のフォームが表示される。各フォームの表示後3秒でフォームは消え、プログラムの実行終了となる。

 

 

Up