【问题标题】:Python strange multiprocessing with variable name带有变量名的Python奇怪的多处理
【发布时间】:2015-09-08 01:23:56
【问题描述】:

一个简单的例子:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import multiprocessing

class Klass(object):
    def __init__(self):
        print "Constructor ... %s" % multiprocessing.current_process().name

    def __del__(self):
        print "... Destructor %s" % multiprocessing.current_process().name


if __name__ == '__main__':
    kls = Klass()

__del__ 中执行current_process 时出现错误:

Constructor ... MainProcess
Exception AttributeError: "'NoneType' object has no attribute 'current_process'" in <bound method Klass.__del__ of <__main__.Klass object at 0x7f5c34e52090>> ignored

如果我更改变量名:

als = Klass()

得到正确的结果:

Constructor ... MainProcess
... Destructor MainProcess

我尝试了很多变量名,有些正常,有些错误。

为什么不同的实例名称,会导致__del__中的多处理模块为None?

【问题讨论】:

  • 我看到了同样的结果……这很奇怪!
  • 这里也一样。产生同样奇怪的结果。所以我猜你在multiprocessing 中发现了一个错误。
  • @jonrsharpe 查看 unutbu 的回答
  • @Sait 查看 unutbu 的回答

标签: python multiprocessing


【解决方案1】:

代码引发

AttributeError: "'NoneType' object has no attribute 'current_process'"

如果在删除kls 之前删除了全局变量multiprocessing。 一般来说,删除对象的顺序是不可预测的。但是,per the docs

从 1.5 版开始,Python 保证名称以下划线开头的全局变量会在其他全局变量被删除之前从其模块中删除;如果不存在对此类全局变量的其他引用,这可能有助于确保在调用 __del__() 方法时导入的模块仍然可用。

因此,如果您将实例命名为_kls(带下划线),那么您可以放心,它的__del__ 将在multiprocessing 被删除之前被调用:

import multiprocessing 

class Klass(object):
    def __init__(self):
        print "Constructor ... %s" % multiprocessing.current_process().name

    def __del__(self):
        print "... Destructor %s" % multiprocessing.current_process().name


if __name__ == '__main__':
    _kls = Klass()

产量

Constructor ... MainProcess
... Destructor MainProcess

Other methods 确保在删除模块之前调用 del 方法包含

  • 使用atexit
  • 使用上下文管理器
  • 将对模块的引用保存为Klass 的属性。

【讨论】:

  • 非常感谢!我应该更加注意python文档的warning部分。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-23
  • 2014-10-09
  • 1970-01-01
  • 1970-01-01
  • 2016-05-31
相关资源
最近更新 更多