簡體   English   中英

python多處理中的意外行為

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM