Reputation: 9
Whenever i use xxx.join() it never works, eitehr just stops and doesnt carry on the rest of the code or crashes my program. in this case crashing my program. i usually make do without it, but for my current program i am trying to allow the client to wait for a message from the server, and i need .join() to allow this without crashing. new_message only crashes my program and doesnt allow the new gui to form. No errors come up in terminal, just crashes
def email_verify_gui():
# new gui
email_entry.destroy()
username_entry.destroy()
createpassword_entry.destroy()
confirmpassword_entry.destroy()
invalid_passwords.destroy()
invalid_boxes.destroy()
next_button.destroy()
S2.configure(text="Verify your email.")
img2 = customtkinter.CTkImage(dark_image=Image.open("emailverify2.png"), size=(250, 175))
subtitle = customtkinter.CTkLabel(master=frame_signup, text=("Complete the tab we opened "
"so that we can verify your email."),
text_color="#fff", font=("Century Gothic", 16), wraplength=300)
subtitle.place(x=27, y=90)
email_img = customtkinter.CTkLabel(master=frame_signup, image=img2, text="")
email_img.place(x=35, y=130)
def server_email():
server_email_status = False
client.send(("send email").encode())
client.send(new_email.encode())
print(new_email)
file_path = "C:\\Users\\gunne\\PycharmProjects\\Playground\\email verification html.html"
webbrowser.open(file_path, new=2)
def new_message():
while True:
server_verify_message = client.recv(2048).decode()
if server_verify_message:
print(server_verify_message)
break
thread_email_verify_gui = threading.Thread(target=email_verify_gui)
thread_server_email = threading.Thread(target=server_email)
thread_new_message = threading.Thread(target=new_message)
print("Threads Established")
thread_email_verify_gui.start()
#thread_email_verify_gui.join()
print("STAGE 1")
thread_server_email.start()
#thread_server_email.join()
print("STAGE 2")
works without the .join() but crashes my program still for as long as i use new_message()
Upvotes: 0
Views: 8863
Reputation: 54
I can see 2 issues :
.join()
on a thread that performs blocking operations will freeze the main thread, causing the GUI to become unresponsive, if this is what you mean by "crash"Start threads without .join()
threading.Thread(target=server_email).start()
threading.Thread(target=new_message).start()
Communicate with the Main Thread Using a Queue
import queue
import threading
message_queue = queue.Queue()
def new_message():
server_verify_message = client.recv(2048).decode()
if server_verify_message:
message_queue.put(server_verify_message)
def check_for_messages():
try:
while True:
message = message_queue.get_nowait()
print(message)
except queue.Empty:
pass
root.after(100, check_for_messages)
check_for_messages()
threading.Thread(target=new_message).start()
Upvotes: 1
Reputation: 188
You will need to use ThreadPoolExecutor
to achieve this basicaly it's allow you to add a call back on a thread.
from concurrent.futures import ThreadPoolExecutor
def email_verify_gui():
# new gui
email_entry.destroy()
username_entry.destroy()
createpassword_entry.destroy()
confirmpassword_entry.destroy()
invalid_passwords.destroy()
invalid_boxes.destroy()
next_button.destroy()
S2.configure(text="Verify your email.")
img2 = customtkinter.CTkImage(dark_image=Image.open("emailverify2.png"), size=(250, 175))
subtitle = customtkinter.CTkLabel(master=frame_signup, text=("Complete the tab we opened "
"so that we can verify your email."),
text_color="#fff", font=("Century Gothic", 16), wraplength=300)
subtitle.place(x=27, y=90)
email_img = customtkinter.CTkLabel(master=frame_signup, image=img2, text="")
email_img.place(x=35, y=130)
def server_email():
server_email_status = False
client.send(("send email").encode())
client.send(new_email.encode())
print(new_email)
file_path = "C:\\Users\\gunne\\PycharmProjects\\Playground\\email verification html.html"
webbrowser.open(file_path, new=2)
def new_message():
while True:
server_verify_message = client.recv(2048).decode()
if server_verify_message:
print(server_verify_message)
break
executor = ThreadPoolExecutor(max_workers=3)
future = executor.submit(email_verify_gui)
future.add_done_callback(lambda x:server_email)
future.add_done_callback(lambda x:new_message)
For more information -> https://superfastpython.com/threadpoolexecutor-in-python
Upvotes: 0