Handle multiple messages with Queue get()
Question: Thanks to @user5402 for the previous
[solution](https://stackoverflow.com/questions/27487207/how-to-run-a-thread-
more-than-once-in-python/27488251?noredirect=1#comment43421261_27488251).

I am trying to handle multiple messages that are queued up. Here is the code:

    
    
    import sys
    import socket
    from multiprocessing import Process, Queue
    
    UDP_ADDR = ("", 13000)
    
    def send(m):
        sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 
        sock.sendto(m, UDP_ADDR)
    
    def receive(q):
        buf = 1024
        Sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        Sock.bind(UDP_ADDR)
        while True:
            (data, addr) = Sock.recvfrom(buf)
            q.put(data)
    

In the client function I want to handle multiple messages, that have knock on
affects.

    
    
    def client():
        q = Queue()
        r = Process(target = receive, args=(q,))
        r.start()
    
        print "client loop started"
        while True:
            m = q.get()
            print "got:", m
            while m == "start":
                print "started"
                z = q.get()
                if z == "stop":
                    return
        print "loop ended"
        r.terminate()
    

So when `start` is sent, it then goes into a while loop that is infinitely
printing `"started"`, and waiting for the `stop` message to come through. The
above `client` code does not work.

Here is the code to start the function:

    
    
    if __name__ == '__main__':
        args = sys.argv
        if len(args) > 1:
            send(args[1])
        else:
            client()
    


Answer: You can write the client loop like this:

    
    
    print "client loop started"
    while True:
        m = q.get()
        print "waiting for start, got:", m
        if m == "start":
          while True:
            try:
              m = q.get(False)
            except:
              m = None
            print "waiting for stop, got:", m
            if m == "stop":
              break
    

Based on your comments, this would be a better approach:

    
    
    import sys
    import socket
    import Queue as Q
    import time
    from multiprocessing import Process, Queue
    
    UDP_ADDR = ("", 13000)
    
    def send(m):
        sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 
        sock.sendto(m, UDP_ADDR)
    
    def receive(q):
        buf = 1024
        Sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        Sock.bind(UDP_ADDR)
        while True:
          (data, addr) = Sock.recvfrom(buf)
          q.put(data)
    
    def doit():
      # ... what the processing thread will do ...
      while True:
        print "sleeping..."
        time.sleep(3)
    
    def client():
      q = Queue()
      r = Process(target = receive, args=(q,))
      r.start()
    
      print "client loop started"
      t = None   # the processing thread
      while True:
          m = q.get()
          if m == "start":
            if t:
              print "processing thread already started"
            else:
              t = Process(target = doit)
              t.start()
              print "processing thread started"
          elif m == "stop":
            if t:
              t.terminate()
              t = None
              print "processing thread stopped"
            else:
              print "processing thread not running"
          elif m == "quit":
            print "shutting down"
            if t:
              t.terminate()
              t = None  # play it safe
            break
          else:
            print "huh?"
      r.terminate()
    
    if __name__ == '__main__':
      args = sys.argv
      if len(args) > 1:
        send(args[1])
      else:
        client()
    

