限制子进程的数量。Popen

问题描述 投票:2回答:1

run multiple instances of python script simultaneously开始,我现在可以编写一个python程序来运行多个实例。

import sys
import subprocess

for i in range(1000):
  subprocess.Popen([sys.executable, 'task.py', '{}in.csv'.format(i), '{}out.csv'.format(i)])

这将同时启动1000个子过程。如果运行每个子进程的命令占用大量计算资源,则这可能会导致计算机上的负载(甚至可能崩溃)。

是否可以限制一次运行的子流程数量?例如这样的东西:

if (#subprocess_currently_running = 10) {
   wait(); // Or sleep 
}

即一次只允许运行10个子进程。万一十分之一完成一个新的。

python-3.x subprocess
1个回答
1
投票

Counting Semaphore是一种过时的机制,可用于控制/管理并发运行的线程/进程的最大数量。

但是由于每个subprocess.Popen对象(暗含过程)需要为waited才能终止,因此官方文档告诉我们subprocess.Popen.wait()的重要缺点(对于这种情况,有多个并发子过​​程:]

注:该函数是使用忙循环(非阻塞调用和短暂睡眠)实现的。将asyncio模块用于异步等待:请参见asyncio.create_subprocess_exec

因此,最好切换到:


如何实现:

import asyncio
import sys

MAX_PROCESSES = 10


async def process_csv(i, sem):
    async with sem:  # controls/allows running 10 concurrent subprocesses at a time
        proc = await asyncio.create_subprocess_exec(sys.executable, 'task.py',
                                                    f'{i}in.csv', f'{i}out.csv')
        await proc.wait()


async def main():
    sem = asyncio.Semaphore(MAX_PROCESSES)
    await asyncio.gather(*[process_csv(i, sem) for i in range(1000)])


asyncio.run(main())
© www.soinside.com 2019 - 2024. All rights reserved.