![](/img/trans.png)
[英]Python Multiprocessing - Process Termination (cannot start a process twice)
[英]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()
现在我正在获取PicklingError: Can't pickle <function printA at 0x00000273F97FF1E0>: it's not the same object as __main__.printA
我不确定如何解决此问题。 我觉得这是在我的工作unix机器上工作的,这是Windows的事情吗?
我希望子进程在完成时自行终止。 我尝试在最后用sys.exit()
包装该函数,并将其用作Process的目标,但是sys.exit()
似乎无法正确终止僵尸进程。 正确的方法是什么?
我不想执行阻塞join()
,也不想设置daemon=True
。 最终目标是有人可以导入此模块,将@async放在任何函数上,它将在单独的进程中运行,然后在到达函数末尾时自行终止。
酸洗错误 :我可以重现该问题。 在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()
僵尸进程 :要避免僵尸进程,您需要让父进程读取其子进程的退出代码,您需要在子进程的父进程中运行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.