python - Killing a multiprocess pool using a tkinter button -


i'm building application thousands (possibly millions) of calculations based off of user inputs. because these calculations can take long time, want use python's multiprocessing module. here dilemma; want set tkinter window cancel button stop calculations running throughout processors set using pool. tried using threads allow popup window run, funny things happen when run code.

when press 'start' button, pool starts going expected. however, popup window not show though on own thread. weirder, when tell ide (pycharm) stop program, popup window shows , calculations still running until either press 'exit' button popup window, or kill program altogether.

so questions are: why won't popup window show though on own thread? utilizing multiprocessing module correctly? or problem totally different?

import tkinter tk tkinter import ttk import random import threading import time multiprocessing import pool  def f(x):     print(x*x)     time.sleep(random.randrange(1,5))  # simulates long calculations     # math stuff here...  def processor():     global calc     calc = pool(4)     calc.map(f, [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30])     print("done")  def calculation_start():     p = threading.thread(target=progress_window)  # thread open new window user cancel calculation     p.start()     processor()  # calls function run calculations  def progress_window():     # window pops let user cancel calculation.     popup = tk.toplevel()     endbutton = ttk.button(popup, text="end", command=lambda :(calc.terminate()))     endbutton.pack()   master = tk.tk()  startbutton = ttk.button(master, text="start", command=calculation_start) startbutton.pack()  tk.mainloop() 

edit: tried switching processor function thread instead of progress_window function.

def calculation_start():     p = threading.thread(target=processor)  # thread function run calculations     p.start()     progress_window()  # open new window user cancel calculation 

my popup window appears , 'end' button looks stops processor when pressed, never continues past point. it's it's stuck @ calc.map(f, [1,2,3,...] in processor() function.

from pool.map documentation:

it blocks until result ready.

that means that, yes, work being done on other threads, main thread (the 1 calling map) not execute else until other threads complete. want use map_async , (for long-running, interactive process), provide callback when pool finished (probably hide pop-up).

if want program show pop-up exit, want use asyncresult returned map_async. set idle handler using after_idle (see tkinter universal widget methods , remember you'll need manually re-add handler after every call). after each idle call, call either asyncresult.ready() or asyncresult.get(<timeout>) see if pool has completed. once it's finished, you're safe process results , exit.


Comments