2

Following from run multiple instances of python script simultaneously I can now write a python program to run multiple instances.

import sys
import subprocess

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

This starts 1000 subprocess simultaneously. If the command that each subprocess is runs is computationally resource intensive, this can result in load on the machine (may even crash).

Is there a way where I can restrict the number of subprocess to be run at a time? For example something like this:

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

That is just allow 10 subprocess to run at a time. In case one out of ten finishes start a new one.

Pushpa
  • 448
  • 3
  • 10

1 Answers1

1

Counting Semaphore is an old-good mechanism which can be used to control/manage the maximum number of concurrently running threads/processes.

But as each subprocess.Popen object (implying process) needs to be waited for termination, the official doc tells us about the important downside of subprocess.Popen.wait()(for this case of multiple concurrent sub-processes):

Note: The function is implemented using a busy loop (non-blocking call and short sleeps). Use the asyncio module for an asynchronous wait: see asyncio.create_subprocess_exec.

Thus, it's preferable for us to switch to:


How it can be implemented:

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())
RomanPerekhrest
  • 88,541
  • 4
  • 65
  • 105
  • Thanks. Worked perfectly. Really helpful was the implementation you presented. Cheers. Although restricting memory is still an issue; an orthogonal one. – Pushpa Feb 19 '20 at 14:13