释放锁之类的事情不应该是在__del__
方法中做的事情,最好在语句中使用锁作为上下文管理器with
来确保锁的释放。
除此之外,生成的类实例存在于不同的进程中,更改子进程中的任何内容都不会影响其他子进程,当然用于 IPC 的对象除外(如队列、管道、锁等)多处理模块)。
另一件事是:返回给主流程的实例与子流程中创建的实例不同。多处理中的返回值在子进程中被腌制,发送到父进程并在那里取消腌制。此过程涉及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