19

There's an instrument on my LAN that sends a UDP data packet every 5-10 ms. In my application, I have a reader thread that allocates a socket with a large buffer when it starts, then enters an infinite loop to read the accumulated packets, parse them, write them to a spooler, then sleep for half a second (time.sleep(0.500)).

I have several lazy consumers for the data, most of which do archiving or generate passive statistics. But one consumer (for display) needs up-to-the-moment data, and needs to wake the sleeping reader (to read the socket) before querying the spooler.

What is the best way to wake a sleeping thread?

(Or, alternately, is there a better way for a thread to sleep that's easier to wake?)

martineau
  • 119,623
  • 25
  • 170
  • 301
BobC
  • 1,978
  • 3
  • 24
  • 26
  • Why do you need to sleep at all? – Martin James Apr 03 '14 at 21:59
  • Because it is more efficient to do so. – BobC Apr 07 '14 at 13:09
  • @BobC: It is typically even more efficient to *wait* for the actual event to happen and not to *poll* regularly whether the event already happened. E.g. using `select` to wait for file descriptor activity. https://docs.python.org/3/library/select.html – Marcel Waldvogel Aug 16 '19 at 14:35
  • @MarcelWaldvogel: `select` is not available on all OSs. – martineau Dec 14 '21 at 23:53
  • Python `select` is exposed on all Unix/POSIX-ish OSes and *for sockets* also on Windows. So, in a network context, it is available on "all" OSes. If it is just timeout/notify, as the answer suggests, then there is no need for `select`. (And if you need [`select` and signals, there is `pselect()`](https://netfuture.ch/2016/02/pselect-pitfalls/) or [`signalfd()`](https://man7.org/linux/man-pages/man2/signalfd.2.html), of course only on POSIX or Linux, respectively.) – Marcel Waldvogel Dec 16 '21 at 09:34

1 Answers1

28

I had failed to notice that threading.condition.wait() has an optional timeout argument!

The answer is to create a condition object and use its wait() method with the optional timeout instead of time.sleep(). If the thread needs to be woken prior to the timeout, call the notify() method of the condition object.

Nick ODell
  • 15,465
  • 3
  • 32
  • 66
BobC
  • 1,978
  • 3
  • 24
  • 26