“select” on multiple Python multiprocessing Queues?

前端 未结 8 1518
情书的邮戳
情书的邮戳 2020-12-24 01:55

What\'s the best way to wait (without spinning) until something is available in either one of two (multiprocessing) Queues, where both reside on the same system?

8条回答
  •  清歌不尽
    2020-12-24 02:27

    Not sure how well the select on a multiprocessing queue works on windows. As select on windows listens for sockets and not file handles, I suspect there could be problems.

    My answer is to make a thread to listen to each queue in a blocking fashion, and to put the results all into a single queue listened to by the main thread, essentially multiplexing the individual queues into a single one.

    My code for doing this is:

    """
    Allow multiple queues to be waited upon.
    
    queue,value = multiq.select(list_of_queues)
    """
    import queue
    import threading
    
    class queue_reader(threading.Thread):
        def __init__(self,inq,sharedq):
            threading.Thread.__init__(self)
            self.inq = inq
            self.sharedq = sharedq
        def run(self):
            while True:
                data = self.inq.get()
                print ("thread reads data=",data)
                result = (self.inq,data)
                self.sharedq.put(result)
    
    class multi_queue(queue.Queue):
        def __init__(self,list_of_queues):
            queue.Queue.__init__(self)
            for q in list_of_queues:
                qr = queue_reader(q,self)
                qr.start()
    
    def select(list_of_queues):
        outq = queue.Queue()
        for q in list_of_queues:
            qr = queue_reader(q,outq)
            qr.start()
        return outq.get()
    

    The following test routine shows how to use it:

    import multiq
    import queue
    
    q1 = queue.Queue()
    q2 = queue.Queue()
    
    q3 = multiq.multi_queue([q1,q2])
    
    q1.put(1)
    q2.put(2)
    q1.put(3)
    q1.put(4)
    
    res=0
    while not res==4:
        while not q3.empty():
            res = q3.get()[1]
            print ("returning result =",res)
    

    Hope this helps.

    Tony Wallace

提交回复
热议问题