从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个子进程。万一十分之一完成一个新的。
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())