For the time being I'm going to get you the error in your code, because I need to analyze with more time, but an alternative to the problem is to use the asyncio
module, since the actual processing of your program runs outside of Python, then you will not have problems with GIL . Basically you will only be using Python to start the processes.
With asyncio
, you could do something similar to:
import asyncio
async def command(*args):
process = await asyncio.create_subprocess_exec(*args, stdout=asyncio.subprocess.PIPE)
stdout, stderr = await process.communicate()
return stdout.decode() if process.returncode == 0 else stderr.decode()
Since I can not reproduce the same command you want with ffmpeg
, I'll demonstrate a code that does ping
on multiple servers. So:
URLS = [
'woss.eng.br',
'pt.stackoverflow.com',
'chat.stackexchange.com',
'127.0.0.1'
]
commands = [command('ping', '-c', '10', url) for url in URLS]
The list commands
will be composed of all the commands that I want to execute in parallel, that is, in this case, the ping
command on the four servers indicated. So, just set the asyncio
event loop and wait for responses:
loop = asyncio.get_event_loop()
processes = asyncio.gather(*commands)
result = loop.run_until_complete(processes)
loop.close()
print(result)
The complete code, with some print
more to follow the execution, would be:
import asyncio, time
async def command(*args):
process = await asyncio.create_subprocess_exec(*args, stdout=asyncio.subprocess.PIPE)
print('Iniciado o processo', process.pid)
stdout, stderr = await process.communicate()
return stdout.decode() if process.returncode == 0 else stderr.decode()
URLS = [
'woss.eng.br',
'pt.stackoverflow.com',
'chat.stackexchange.com',
'127.0.0.1'
]
START = time.time()
commands = [command('ping', '-c', '10', url) for url in URLS]
loop = asyncio.get_event_loop()
processes = asyncio.gather(*commands)
result = loop.run_until_complete(processes)
loop.close()
END = time.time()
print(result)
print('Tempo', END - START)
See working at Repl.it
Running, you will see that it will run in approximately 9 seconds, which is the approximate time of the ping
command for a domain, transferring 10 packets, even if four commands were executed, different if the same commands run in sequence , totaling almost 40 seconds.