classification
Title: threading.Event.wait_unset()
Type: enhancement Stage:
Components: Library (Lib) Versions: Python 3.10
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: BlackLight, Jacob Kunnappally
Priority: normal Keywords:

Created on 2020-06-05 13:42 by Jacob Kunnappally, last changed 2020-09-25 14:00 by BlackLight.

Messages (2)
msg370761 - (view) Author: Jacob Kunnappally (Jacob Kunnappally) Date: 2020-06-05 13:42
Just requesting a threading.Event.wait_unset(timeout=None) function. I would request the same for multiprocessing.

My use case:

I've made my own class that adds a little bit of IPC plumbing to the base Process class (ChildProcess). Each ChildProcess has a status that it can update to let other threads/processes know what it's doing at the moment. There is a configurable period when that updated status can be considered "fresh". In some cases, I would like a listening process to be able to ignore the "freshness" and only trigger some action only if the status updates while the listening process is waiting for it to update.

To do this, I need to be able to know when the status goes unfresh so that waiting for the status to update can begin in earnest. Right now I am polling manually, and that can't be the right answer.

Happy to clarify the above paragraphs. That's as best as I could think to describe it in text.
msg377492 - (view) Author: Fabio Manganiello (BlackLight) Date: 2020-09-25 14:00
+1

I have similar applications (both using multithreading and multiprocessing) which rely upon waiting for events to be both set and unset. Some example common pattern:

```
from multithreading import Thread, Event, Queue
import time

q = Queue()
reading = Event()

def read_from_device(device):
    # Wait for the caller to signal that it's ready to receive
    reading.wait()
    data = get_data(device)

    while data:
        data = get_data(device)
        q.put(data)

    # Once we're done receiving data, wait for the caller to
    # signal that it has received everything
    while reading.is_set():
        time.sleep(1)

    # Do some other operations once all threads are in sync
    release_device(device)

processor = threading.Thread(target=read_from_device, args=(device,))
processor.start()

# Do something else

reading.set()

# Get data from the processor
data = q.get()
while data:
    preprocess_data(data)
    data = q.get()

# Do something before we're ready to clean up everything
process_data()

# Signal to the processor that we're done
reading.clear()
```

Events (and I'd say that this also applies to Conditions) are supposed to be symmetric - one can either wait for an event to be set or cleared - but the implementation provided by the current API is definitely asymmetric - `wait()` can be used to wait for an event to be set, but if you want to wait for it to be cleared then the only provided approach is through a poll on `is_set()`.
History
Date User Action Args
2020-09-25 14:00:30BlackLightsetnosy: + BlackLight
messages: + msg377492
2020-06-05 13:42:51Jacob Kunnappallycreate