Reputation: 943
I have a very simple example of decorators and multithreading. However, there are several issues I can't resolve:
1.) There is a race condition at change_print_event_handler()
. The "PRINT" event before it always seems to get called after it executes.
2.) The print event "this may no longer matter to you"
does not get called at all, unless:
a.) add event_loop_thread.join()
to the end of the thread.
b.) add a sleep time to the end to the event joiner function
c.) Make the event_loop_thread = threading.Thread(target=event_loop, daemon=True)
line say daemon = false.
All of these "unless" solutions, however, cause the program to hang indefintely.
I would appreciate any explanation of how this might be addressed, either by restructuring the program entirely or by adding or changing a few lines.
import threading
import queue
import time
event_queue = queue.Queue();
event_handlers = {}
def register_event(event_type):
def decorator(func):
event_handlers[event_type] = func
return func
return decorator
@register_event("PRINT")
def handle_printer_event(message):
print(f"Print Event: {message}")
@register_event("ALERT")
def handle_alert_event(message):
print(f"Alert! {message}")
def event_loop():
while True:
try:
#event_type, message = event_queue.get(timeout=1)
event_type, message = event_queue.get(timeout=1)
if event_type in event_handlers:
event_handlers[event_type](message)
else:
print(f"No handler for event type: {event_type}")
except queue.Empty:
pass
def add_events():
time.sleep(1)
event_queue.put(("PRINT", "This is a print event"))
time.sleep(2)
event_queue.put(("ALERT", "This is an alert event"))
time.sleep(1)
event_queue.put(("UNKNOWN", "This event has no handler"))
time.sleep(1)
event_queue.put(("PRINT", "This is another print event"))
change_print_event_handler()
time.sleep(1)
event_queue.put(("PRINT", "this may no longer matter to you"))
#time.sleep(1)
def change_print_event_handler():
def game_over_handler(message):
print("Game over")
event_handlers["PRINT"] = game_over_handler
event_loop_thread = threading.Thread(target=event_loop, daemon=True)
event_loop_thread.start()
event_adder_thread = threading.Thread(target=add_events, daemon=True)
event_adder_thread.start()
event_adder_thread.join()
#event_loop_thread.join()
Upvotes: 0
Views: 26