Python multiprocessing.Queue vs multiprocessing.manager().Queue()

前端 未结 2 1273
时光说笑
时光说笑 2020-12-13 09:06

I have a simple task like that:

def worker(queue):
    while True:
        try:
            _ = queue.get_nowait()
        except Queue.Empty:
            br         


        
2条回答
  •  长情又很酷
    2020-12-13 09:08

    I have recently came over a problem with Manager().Queue(), when the SyncManager object - returned by multiprocessing.Manager() - seemingly dies, and the queues it manages block forever (even with *_nowait()).

    I am not sure of the reason, or if the SyncManager really dies, the only clue I have is that I call multiprocessing.Manager() from a class instance, which has __del__(), which logs the process it is called from, and I can see this being __del__() called from the SyncManager process.

    This means that my object has a copy in the SyncManager process, and it is garbage collected. This could mean that only my object was deleted, and the SyncManager is fine, but I do see that the corresponding queues becoming unresponsive correlate to the __del__() call in the SyncManager process.

    I have no idea, how my object ends up in the SyncManager process. I usually pump out 50-200 managers - some with overlapping lifetimes, others not - until I see this problem. For objects that exist when the interpreter exits, __del__() is not called, and I usually not see the SyncManager objects dying by this log from __del__(), only on occasion. Probably when there is a problem, the SyncManager object first disposes of its objects, and only then will the interpreter exit, and this is Why I see the __del__() call on occasion.

    I did see my queue become unresponsive even in cases, where I did not see the __del__() being called from the SyncManager.

    I have also seen the SyncManager "die" without causing further problems.

    By "unresponsive" I mean:

    queue.get(timeout=1)
    queue.put(timeout=1)
    

    never return.

    queue.get_nowait(timeout=1)
    queue.put_nowait(timeout=1)
    

    never return.

    This became a bit more involved, then I originally wanted, but I let the details in, just in case it helps someone.

    I used Manager().Queue() for a long time before without any problems. I suspect that either instantiating a lot of manager objects caused the problem, or instantiating a lot of managers led to a problem that has always existed surface.

    I use Python 3.6.5.

提交回复
热议问题