python - 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
等),而是退出而没有任何输出。
我在这里遗漏了一些明显的东西吗?为什么会这样?
解决方案
推荐阅读
- firebase - 将 Firebase 导出到 Bigquery 数据集的生存时间
- reactjs - 如何从 reactjs 中的事件处理程序访问更新的状态
- html - 按钮上的按钮转换:活动
- python - 创建一个可视化指标图,将收益分为高、正常和低
- java - 如何在 Maven 子模块中添加 Java Azure Functions
- angularjs - AngularJs - 在没有控制器的情况下分配和重新定义变量,打破循环
- flask - 使用域名在 IIS 中托管 Flask 应用程序的最佳实践
- generics - 我如何获得警告 FS1125(泛型类型 'xxx' 的实例化丢失并且无法从中推断出......)消失?
- c# - C#算法合并两个无重复的排序数组
- pandas - 数据框 Sort_values 给出不正确的结果