首页 > 解决方案 > multiprocessing.Queue.put_nowait 在析构函数中使用时阻塞

问题描述

multiprocessing.Queue当另一个进程中具有此队列作为属性的对象被删除时,我正在尝试使用 a进行通信。在这样做的同时,我注意到在某些情况下无论如何Queue.put()使用block=False(或等效地Queue.put_nowait())块并将其归结为以下最小可重现示例:

import multiprocessing as mp

class A:
  def __init__(self):
    self.q = mp.Queue()
    # uncommenting this makes it work fine:
    # self.q.put("test")

  def __del__(self):
    print("before putting CLOSE")
    self.q.put_nowait("CLOSE")
    print("after putting CLOSE")

a = A()

# uncommenting this also makes it work fine:
# del a

运行此代码,输出达到

before putting CLOSE

然后它无限期地冻结。

我不知道这里发生了什么以及为什么会发生这种情况。Queue.put_nowait()当且仅当从对象的析构函数 ( __del__())调用它并且之前没有将数据放入其中并且由于对象超出范围而不是由于显式而调用析构函数时,似乎才会阻塞del。如果队列是全局变量而不是 的属性,同样的事情也会发生A,只要在的析构函数put_nowait()中调用。A

Ctrl有趣的是,使用+中止脚本C不会导致通常的异常输出(KeyboardInterrupt等),而是退出而没有任何输出。

我在这里遗漏了一些明显的东西吗?为什么会这样?

标签: pythonqueuepython-multiprocessing

解决方案


推荐阅读