限制从python脚本一次运行的进程数

MVa*_*der 4 python multithreading multiprocessing python-multithreading python-multiprocessing

我正在运行一个备份脚本,启动子进程以通过rsync执行备份.但是我无法限制它一次启动的rsyncs的数量.

这是我目前正在处理的代码:

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()
Run Code Online (Sandbox Code Playgroud)

当我运行数百个rsyncs时,这显示最多一个孩子.这是实际启动rsync的代码(来自do_backup函数内部).command是包含rsync行的变量:

print command
subprocess.Popen(command, stdout=subprocess.PIPE, shell=True)
return 1
Run Code Online (Sandbox Code Playgroud)

如果我向do_backup函数添加sleep(x),它将在睡眠时显示为活动子项.另外,进程表被显示为具有1我是从这个是rsync的分裂关闭,不再是蟒蛇的孩子,让我的子进程死,所以我不能再指望它假设PPID rsync的过程.有没有人知道如何保持python子活着并被计算直到rsync完成?

JoE*_*anO 6

多处理池

你有没有想过使用多处理.Pool的?这些允许您定义用于执行所需作业的固定数量的工作进程.这里的关键字是固定数字,它可以让您完全控制将要启动的rsync实例数.

看着我链接的文档中提供的例子,首先你宣布Pooln进程,然后你可以决定是否要map()apply()(与各自的_async()兄弟姐妹)作业到池.

from multiprocessing import Pool

def f(x):
    return x*x

if __name__ == '__main__':
    pool = Pool(processes=4)              # start 4 worker processes

    pool.apply_async(f, (10,))    # evaluate "f(10)" asynchronously
    ...
    pool.map(f, range(10))
Run Code Online (Sandbox Code Playgroud)

这里的明显优势是你永远不会意外地对你的机器进行分叉炸弹,因为你只会产生所请求的n进程.

运行rsync

您的流程生成代码将变为类似于:

from multiprocessing import Pool

def do_backup(arg1, arg2, arg3, ...):
    # Do stuff

if __name__ == '__main__':
    # Start a Pool with 4 processes
    pool = Pool(processes=4)
    jobs = []

    for ... :
        # Run the function
        proc = pool.apply_async(func=do_backup, args=(shash["NAME"],ip,shash["buTYPE"], ))
        jobs.append(proc)

    # Wait for jobs to complete before exiting
    while(not all([p.ready() for p in jobs])):
        time.sleep(5)

    # Safely terminate the pool
    pool.close()
    pool.join()
Run Code Online (Sandbox Code Playgroud)