Chris
Chris

Reputation: 71

Best way to respond quickly to a variable that is changed by another thread

I have written a program to consume data that I am sending to it via UDP packets every 10 milliseconds. I am using separate threads because it can take a variable amount of time to run the logic to process the data and if more than 10ms have elapsed I just want it to process the most recently received datagram. I am currently running a while loop and checking every millisecond for a new quote via time.sleep(0.001). I just learned that this time.sleep() is actually taking up to 16 milliseconds to process on a windows server 2019 operating system and it is delaying everything. I could just put pass instead of time.sleep but this ends up using too much CPU (I am running multiple instances of the program). Is there a way I can have the program pause and just wait for maindata.newquote == True before proceeding? The trick is I would like it to respond very quickly (in less than a millisecond) rather than waiting for the next windows timer interrupt.

class maindata:
  newquote = False
  quote = ''
  

def startquotesUDP(maindata,myaddress,port):
  UDPServerSocket = socket(family=AF_INET, type=SOCK_DGRAM)
  UDPServerSocket.bind((myaddress, port))  
  while True:
    bytesAddressPair = UDPServerSocket.recvfrom(bufferSize)
    #parse raw data
    maindata.quote = parsed_data
    maindata.newquote = True

threading.Thread(target=startquotesUDP,args=(maindata,address,port,)).start()

while True:
  if maindata.newquote == False:
    time.sleep(0.001)               #This is what I want to improve
  else:
    #process maindata.quote
    maindata.newquote = False

Upvotes: 0

Views: 67

Answers (1)

Frank Yellin
Frank Yellin

Reputation: 11283

My answer is the same as @balmy above, but I wouldn't even bother with a semaphore.

The producer just writes to a queue

while True:
    result = ...
    queue.put(result)
    sleep as necessary

The receiver can receive every result by doing

while True:
    result = queue.get()
    handle result

If you prefer only to see the most recent result sent by the producer, in case it has send multiple results since the last time you looked, then:

while True:
    result = queue.get()
    while not queue.empty():
        result = queue.get()
    handle result

Upvotes: 1

Related Questions