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
関数inputをif __name__ == '__main__'のブロックの外で実行したときに起こる問題は、実行環境に依存している。端末Windows PowerShellにおいてリスト2のスクリプトを実行すると図4のようになる。
図4
関数printとinputによる出力が何回か行われ、Enterキーを数回押せば図2のフォームが表示される。各フォームの表示後3秒でフォームは消え、プログラムの実行終了となる。