[英]Unexpected behaviour in python multiprocessing
我試圖了解使用python mutiprocessing
觀察到的以下奇怪行為。
示例testClass:import os導入多處理
class testClass(multiprocessing.Process):
def __del__(self):
print "__del__ PID: %d" % os.getpid()
print self.a
def __init__(self):
multiprocessing.Process.__init__(self)
print "__init__ PID: %d" % os.getpid()
self.a = 0
def run(self):
print "method1 PID: %d" % os.getpid()
self.a = 1
和一些測試程序:從testClass導入testClass
print "Start"
proc_list = []
proc_list.append(testClass())
proc_list[-1].start()
proc_list[-1].join()
print "End"
這將產生:
Start
__init__ PID: 89578
method1 PID: 89585
End
__del__ PID: 89578
0
為什么不打印1
?
我猜這與可以在不同進程上實際執行run
這一事實有關。 如果這是預期的行為,那么每個人都如何在進程需要昂貴的__init__
使用多處理?
而且是否應該在多處理文檔中更好地突出這種行為?
您可以將昂貴的初始化包裝在上下文管理器中:
def run(self):
with expensive_initialization() as initialized_object:
do_some_logic_here(initialized_object)
您將有機會在調用do_some_logic_here
之前正確初始化對象,並在離開上下文管理器的塊之后正確釋放資源。
請參閱文檔 。
調用start()
,解釋器將派生並創建一個子進程,該子進程從父級獲取頁表的副本。 這些指向標記為只讀且僅在寫入(COW)時復制的頁面。 解釋器,在執行時run
的子進程,訪問孩子的副本PyObject
代表a
。 父母的記憶沒有被觸及。 子級還會獲取文件描述符表的副本,這意味着如果父級打開了連接,則該文件描述符將由子級繼承。 您可以看到(使用strace
)該子對象是通過不帶CLONE_FILES
clone
創建的:
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f460d8929d0)
因此,從克隆手冊頁:
如果未設置CLONE_FILES,則子進程將繼承clone()時在調用進程中打開的所有文件描述符的副本。 (子級中重復的文件描述符與調用過程中的相應文件描述符引用相同的打開文件描述(請參閱open(2))。)由以下操作打開或關閉文件描述符或更改文件描述符標志的后續操作調用進程或子進程都不會影響其他進程。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.