Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python threading.Event reset?

I have a function that I want to run repeatedly on threading.Events. However it looks like you can only use each Event instance a single time.

Is there a way to reset the thread.Event so that it can be triggered again? I imagine it could look something like this:

import threading
import time


def waiting_function(trigger):
    while True:
        trigger.wait()
        # do stuff after trigger
        trigger.reset()

trigger = threading.Event()

waiting_thread = threading.Thread(target=waiting_function, args=[trigger])
waiting_thread.start()

time.sleep(3.)  # do some stuff that takes a while
trigger.set()
time.sleep(3.)  # do some stuff that takes a while
if not trigger.is_set:
    trigger.set()

Alternatively, do I have to create a new trigger after each set and share it between the threads?

like image 398
ericksonla Avatar asked Apr 10 '26 21:04

ericksonla


1 Answers

I ran into a similar situation where I needed an automatically resetting threading.Event. (I was inspired by .NET, which already has this as System.Threading.AutoResetEvent.) The correct implementation depends on what should happen if the event is signaled while there is no waiting thread. Should that signal be saved so that the next waiting thread does not block at all or should that signal be lost?

a) If the signal should be saved, this is easy. Like Raymond Chen says, an auto-reset event is just a semaphore with a count of 1. Use a threading.BoundedSemaphore.

# in the signaling thread
semaphore = threading.BoundedSemaphore()
# in case the signaling thread signals more frequently than the waiting thread waits
with contextlib.suppress(ValueError):
   semaphore.release()
def waiting_function(semaphore):
    while True:
        semaphore.acquire()
        # do stuff after trigger

b) If the signal should be thrown away if there is no waiting thread, use a threading.Condition. This implementation is a few more lines of code as Condition requires that its lock is held both before waiting and before signaling.

# in the signaling thread
condition = threading.Condition()
with condition:
   condition.notify_all()
def waiting_function(condition):
    while True:
        with condition:
            condition.wait()
        # do stuff after trigger
like image 199
iforapsy Avatar answered Apr 13 '26 09:04

iforapsy



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!