Using Threading.Event to signal main thread I was reading on this page about using a thread, catching an exception, and notifying the calling thread.

The answer suggested Queue, but in the comments it states:


  Queue is not the best vehicle to communicate an error back, unless you
  want to have a full queue of them. A much better construct is
  threading.Event()


From the Python documentation:


  This is one of the simplest mechanisms for communication between
  threads: one thread signals an event and other threads wait for it.


I'm new to multi threading and I wanted to give it a try, so I came up with this trivial example. I'm unsure if I'm on the right track.

import threading

def dividebyzero(event,first,second):
    try:
        result = first / second
    except ZeroDivisionError:
        event.set()
        print("Can't divide by 0")
    else:
        print(result)


e = threading.Event()
t1 = threading.Thread(name='DivideByZero',target=dividebyzero, args=(e, 10, 0),)

t1.start()
t1.join()

if e.is_set():
    print("Error occurred in division thread")


Question:


Using threading.Event as shown in my example, is it the correct way to signal the main thread an error as occurred?
I'm not using event.wait() because it seems unnecessary, I call join() on the t1 thread, so when I call is_set() hopefully I'll get an accurate result. Is it mandatory to use event.wait() when using threading.event()
I understand that if I needed to raise more exceptions using an event probably isn't ideal, how would you know which exception was raise? In that situation would a Queue be better?


If I were to use event.wait() there is a chance the main thread could hang forever, because if the exception doesn't occur the event is never set.

I don't have an error or problems with the code, it works, I just want it reviewed to make sure I used event correctly.
Yes and no. Your approach works, and it is easy to understand. If, however, you want to keep track of what type of exception was raised, it could be improved. What if you have some super complex function that can raise 10 different exceptions, and you need access to the exception traceback if something goes wrong? You'd need 10 threading.Event instances. In that case, you should use a queue.Queue instead, which is thread-safe (untested snippet):

import queue
import threading

def dividebyzero(first, second, exc_queue):
    try:
        result = first / second
    except ZeroDivisionError as exc:
        exc_queue.put(exc)
    else:
        print(result)

excq = queue.Queue()
t = threading.Thread(target=dividebyzero, args=(10, 0, excq))
t.start()
t.join()
if excq.qsize() != 0:
    print(excq.get())

No, it is not mandatory to use threading.Event.wait(). Your observation is right: calling event.wait() might make the thread hang indefinitely.
goto 1;