像释放锁这样的操作不应该在__del__
方法中执行,最好使用锁作为上下文管理器在with
语句中确保释放锁。
此外,生成的类实例存在于不同的进程中,在子进程中更改任何内容都不会影响其他子进程,当然,除了用于IPC的对象(例如来自模块的队列、管道、锁等)。
还有一件事是:返回给主进程的实例不是在子进程中创建的相同实例。在中,返回值在子进程中被pickle,然后发送到父进程并在那里进行unpickle。
这个过程涉及一个ForkingPickler
*。
因此,__del__
不会在同一实例上多次调用,而是在不同子进程中的不同实例上调用。
*:不完全确定这里到底发生了什么,也许有人知道得更多……但也许另一个版本的示例会有所帮助:
import multiprocessing
import time
import os
class myclass(object):
def __init__(self,val):
self.val=val
print ("Initializing %s - %s - %s" % (str(self.val), self, os.getpid()))
def __del__(self):
print ("Deleting %s - %s - %s" % (str(self.val), self, os.getpid()))
if __name__ == "__main__":
p = multiprocessing.Pool(3)
obj_list=p.map(myclass,range(5))
del p
for o in obj_list:
print ("Returned %s - %s - %s" % (str(o.val), o, os.getpid()))
输出:
Initializing 0 - <__main__.myclass object at 0x7f2497fdc0d0> - 7574
Initializing 2 - <__main__.myclass object at 0x7f2497fdc110> - 7574
Deleting 0 - <__main__.myclass object at 0x7f2497fdc0d0> - 7574
Initializing 1 - <__main__.myclass object at 0x7f2497fdc150> - 7575
Initializing 3 - <__main__.myclass object at 0x7f2497fdc1d0> - 7575
Deleting 1 - <__main__.myclass object at 0x7f2497fdc150> - 7575
Initializing 4 - <__main__.myclass object at 0x7f2497fdc0d0> - 7574
Deleting 2 - <__main__.myclass object at 0x7f2497fdc110> - 7574
Returned 0 - <__main__.myclass object at 0x7f2497fdc650> - 7573
Returned 1 - <__main__.myclass object at 0x7f2497fdc7d0> - 7573
Returned 2 - <__main__.myclass object at 0x7f2497fdc810> - 7573
Returned 3 - <__main__.myclass object at 0x7f2497fdc850> - 7573
Returned 4 - <__main__.myclass object at 0x7f2497fdc890> - 7573
Deleting 3 - <__main__.myclass object at 0x7f2497fdc1d0> - 7575
Deleting 4 - <__main__.myclass object at 0x7f2497fdc890> - 7573
Deleting 3 - <__main__.myclass object at 0x7f2497fdc850> - 7573
Deleting 2 - <__main__.myclass object at 0x7f2497fdc810> - 7573
Deleting 1 - <__main__.myclass object at 0x7f2497fdc7d0> - 7573
Deleting 0 - <__main__.myclass object at 0x7f2497fdc650> - 7573
注意不同的进程和对象ID