簡體   English   中英

Python多處理子進程自終止和PickleError

[英]Python Multiprocessing Child Process Self Termination and PickleError

我正在嘗試學習多處理模塊和裝飾器。 我對以下代碼有兩個疑問:

from time import sleep
from multiprocessing import Process

class async:
    def __init__(self, function):
        self.func = function
    def __call__(self, *args, **kwargs):
        p = Process(target = self.func, args = args, kwargs = kwargs)
        p.start()

@async
def printA():
    sleep(1)
    print("A")

def main():
    printA()
    printA()
    printA()

    #do more work

if __name__ == "__main__":
    main()
  1. 現在我正在獲取PicklingError: Can't pickle <function printA at 0x00000273F97FF1E0>: it's not the same object as __main__.printA
    我不確定如何解決此問題。 我覺得這是在我的工作unix機器上工作的,這是Windows的事情嗎?

  2. 我希望子進程在完成時自行終止。 我嘗試在最后用sys.exit()包裝該函數,並將其用作Process的目標,但是sys.exit()似乎無法正確終止僵屍進程。 正確的方法是什么?

我不想執行阻塞join() ,也不想設置daemon=True 最終目標是有人可以導入此模塊,將@async放在任何函數上,它將在單獨的進程中運行,然后在到達函數末尾時自行終止。

  1. 酸洗錯誤 :我可以重現該問題。 在Linux上,它可以正常工作,而在Windows上,則不能。 問題似乎是在Windows上無法正確腌制的裝飾器。 刪除裝飾器將產生此工作代碼(當然這不是您想要的,但可能會說服您嘗試另一種設計方法)。 SO上也有這個線程,它有完全相同的問題。

     from time import sleep from multiprocessing import Process def printA(): sleep(1) print("A") def main(): for i in range(3): p = Process(target = printA) p.start() #do more work if __name__ == "__main__": main() 
  2. 僵屍進程 :要避免僵屍進程,您需要讓父進程讀取其子進程的退出代碼,您需要在子進程的父進程中運行join()來執行此操作。 您可以像這樣在裝飾器中執行此操作:

     class async: def __init__(self, function): self.func = function self.pool = [] def __call__(self, *args, **kwargs): p = Process(target = self.func, args = args, kwargs = kwargs) self.pool.append(p) p.start() def __del__(self): for p in self.pool: p.join() 

這利用了python只執行@async一個實例的@async ,因此您可以將所有進程收集在self.pool 請注意,此操作僅在主進程的出口運行,因為python不會更早刪除異步實例。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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