Python Forum

Full Version: Python multiprocessing Pool apply async wait for process to complete
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
I have coded a simple program of run through the list, but apply_sync isn't waiting until the list is complete, here is the code

import itertools
import multiprocessing
from multiprocessing import Pool
import time
from tkinter import *
from tkinter import ttk
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
import os
from tkinter import messagebox


x= ['annah', 'reena', 'jermy', 'sunny', 'chinni']


def next_name(name):
    options = Options()
    options.binary_location = r'drivers/Browser/chrome.exe'
    driver = webdriver.Chrome(executable_path=r'drivers/chromedriver.exe', options=options)
    driver.get('http://google.com')
    time.sleep(2)
    driver.find_element(By.XPATH, '//input[@name="q"]').send_keys(name)
    time.sleep(2)
    driver.find_element(By.XPATH, '//input[@name="q"]').send_keys(Keys.ENTER)
    time.sleep(3)
    driver.close()

def start():
    global y
    y = Pool(processes=2)
    for usr in itertools.zip_longest(x):
        y.apply_async(next_name, args=(usr, ))
    #messagebox has to popup when list is completed
    messagebox.showinfo("Sample Program", "List Completed")

def stop():
    y.terminate()
    os.system("taskkill /F /IM chromedriver.exe /T")
root = Tk()
startbtn = ttk.Button(root, text="start", command=start)
startbtn.pack()
stopbtn = ttk.Button(root, text="stop", command=stop)
stopbtn.pack()
root.geometry('300x300')
if __name__ == '__main__':
    multiprocessing.freeze_support()
    root.mainloop()
I just want the program to show message box when list was completed.

Any help would be appreciated.

Thank you
If you call the function directly the program will wait and draw the message block when the processes are done. By using apply_async() you are telling python to not wait for completion of the tasks. apply_async() returns an AsyncResult object. This can be used to wait for the process to complete. You can also specify a callback function that is called when the task completes.

You should not block as this will make the user interface unresponsive. I think using the callback is a better idea.

apply_async() is not a good choice for what you are doing. I would go with map_async()

https://docs.python.org/3/library/multiprocessing.html
Thanks for the help deanhystad, i modify the code with map_async, it works fine

def mycallback(x):
    messagebox.showinfo("Sample Program", "Completed")

def start():
    global y
    pool = Pool(processes=2)
    pool.map_async(next_name, x, callback=mycallback)
(Mar-26-2022, 06:48 AM)deanhystad Wrote: [ -> ]If you call the function directly the program will wait and draw the message block when the processes are done. By using apply_async() you are telling python to not wait for completion of the tasks. apply_async() returns an AsyncResult object. This can be used to wait for the process to complete. You can also specify a callback function that is called when the task completes.

You should not block as this will make the user interface unresponsive. I think using the callback is a better idea.

apply_async() is not a good choice for what you are doing. I would go with map_async()

https://docs.python.org/3/library/multiprocessing.html
How we can pass multiple lists in map_async, example

x= ['annah', 'reena', 'jermy', 'sunny', 'chinni']
proxies = ["ip:port:username:password", "ip:port:username:password"]


I want to use the proxies randomly for every launch
Still looking for solution on how to add multiple args to map_async
Lots of choices. I'm sure one fits you needs.

https://docs.python.org/3/library/multip...1a25acdf81

Maybe one of the starmap functions.
Thanks alot @deanhystad i found the solution