繁体   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