Search code examples
pythonpython-3.xtkinterpython-multithreadingthreadpoolexecutor

Python ThreadPoolExecutor is not waiting long enough for task completion


Basically, I need to process (convert form PDF, resize and save) multiple images, and then load them into tkinter. Here's the relevant part of the code.

def part(i):
    global prog
    zoom = 5    # zoom factor
    mat = fitz.Matrix(zoom, zoom)
    page = doc.loadPage(i) #number of page
    pix = page.getPixmap(matrix = mat)
    output = "Output_Images\\Ques_"+str(i+1)+".png"
    pix.writePNG(output)
    prog += ((1/pages)*50)
    progress['value'] = prog
    load.update_idletasks()

executor = concurrent.futures.ThreadPoolExecutor(max_workers = 4)
for i in range(0, pages):
    executor.submit(part, i)

launch_main()

The launch_main() function puts all the images, with a couple of more widgets into a tk.Text within a loop. The problem I am facing is that, there are times when a couple of images at the last (variable in every run) are not getting inserted into the tk.Text.

The Output_Images directory has all the images, which implies that the launch_main() function is being called earlier than expected, and hence it's loop ends before the all the images are saved.

But if I do this instead, i.e., add time.sleep(), it seems to work fine.

executor = concurrent.futures.ThreadPoolExecutor(max_workers = 4)
for i in range(0, pages):
    executor.submit(part, i)
    time.sleep(0.1)

Is there any better solution to this problem? Any help would be appreciated.


Solution

  • I would utilize the ThreadPoolExecutor with the with clause in order to avoid any unexpected behavior.

    with concurrent.futures.ThreadPoolExecutor() as executor:
        for i in range(0, pages):
            executor.submit(part, i)
    
    print("All tasks completed")
    launch_main()