我正在运行一个备份脚本,该脚本启动子进程以通过rsync执行备份。但是,我没有办法限制一次启动的rsync的数量。
这是我目前正在处理的代码:
print "active_children: ", multiprocessing.active_children()
print "active_children len: ", len(multiprocessing.active_children())
while len(multiprocessing.active_children()) > 49:
sleep(2)
p = multiprocessing.Process(target=do_backup, args=(shash["NAME"],ip,shash["buTYPE"], ))
jobs.append(p)
p.start()
当我运行数百个rsync时,这显示最多一个孩子。这是实际启动rsync的代码(从do_backup函数内部),它command
是一个包含rsync行的变量:
print command
subprocess.Popen(command, stdout=subprocess.PIPE, shell=True)
return 1
如果我在do_backup函数中添加sleep(x),它将在睡眠时显示为活动的孩子。进程表还显示rsync进程的PPID为1。据此,我假设rsync会分离并且不再是python的子进程,这会使我的子进程死亡,因此我无法再对其进行计数了。有谁知道如何让python孩子继续生存并被计数直到rsync完成?
让我们先清除一些误解
我从这里假设rsync分裂了,并且不再是python的子级,这使我的子级进程死亡,因此我无法再对其进行计数了。
rsync
做“分裂”。在UNIX系统上,这称为fork。
当一个进程叉,一个子进程被创建-所以rsync
是一个Python的孩子。该子级独立于父级执行-并发执行(“同时”)。
流程可以管理自己的孩子。有特定的系统调用,但是在谈论python时它有点偏离主题,它具有自己的高级接口
如果查看subprocess.Popen
的文档,您会注意到它根本不是函数调用:它是一个类。通过调用它,您将创建该类的实例-Popen对象。这样的对象有多种方法。特别是,wait
它将允许您阻止父进程(python),直到子进程终止。
考虑到这一点,让我们看一下您的代码并将其简化一下:
p = multiprocessing.Process(target=do_backup, ...)
在这里,您实际上是在创建和创建子进程。该进程是另一个python解释器(与所有multiprocessing
进程一样),并将执行该do_backup
函数。
def do_backup()
subprocess.Popen("rsync ...", ...)
在这里,你是分叉再次。您将创建另一个进程(rsync
),并让它“在后台”运行,因为您不需wait
要这样做。
清除所有这些内容后,希望您可以看到使用现有代码的一种方法。如果您想降低它的复杂性,我建议您检查并调整JoErNanO的答案,该答案可以重复使用multiprocessing.Pool
以自动跟踪流程。
无论您决定采用哪种方式,都应避免分叉Popen
来创建rsync
流程-因为这不必要地创建了另一个流程。相反,请检查os.execv
,它将当前过程替换为另一个
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句