0

I am new to python, and my trying to resolve a simple issue: I have two blocks of operations (Block A and Block B), every block execute different shell commands that should be executed async inside the block (in the same block I can execute a new operation, without having to wait the result of the first one).

I can start running the operations of 'Block B' only when all the operations of 'Block A' are finished.

import asyncio
import subprocess
import sys
import threading


async def run_command(number, timeSleep):
    cmd = "(echo '"+ number +" Start -->' $(date) ;sleep "+timeSleep +" ;echo '"+ number +" End -->' $(date) ) >> /tmp/log.txt"

    p = subprocess.Popen(cmd, stderr=subprocess.PIPE, shell=True)

async def block_a():
    await asyncio.gather(
        run_command("Block A: Operation 1","8"),
        run_command("Block A: Operation 2","4"),
        run_command("Block A: Operation 3","2"))

async def block_b():
    await asyncio.gather(
        run_command("Block B Operation 1","5"),
        run_command("Block B Operation 2","4"),
        run_command("Block B Operation 3","1"))


async def main():
    await asyncio.gather(
        block_a(),
        block_b())

if __name__ == '__main__':
    # Create the asyncio event loop
    loop = asyncio.get_event_loop()
    try:
        loop.run_until_complete(main())
    finally:
        # Shutdown the loop even if there is an exception
        loop.close()

I am getting the following output:

Block A: Operation 2 Start --> Thu Apr 9 21:21:27 CEST 2020
Block A: Operation 3 Start --> Thu Apr 9 21:21:27 CEST 2020
Block A: Operation 1 Start --> Thu Apr 9 21:21:27 CEST 2020
Block B Operation 1 Start --> Thu Apr 9 21:21:27 CEST 2020
Block B Operation 2 Start --> Thu Apr 9 21:21:27 CEST 2020
Block B Operation 3 Start --> Thu Apr 9 21:21:27 CEST 2020
Block B Operation 3 End --> Thu Apr 9 21:21:28 CEST 2020
Block A: Operation 3 End --> Thu Apr 9 21:21:29 CEST 2020
Block A: Operation 2 End --> Thu Apr 9 21:21:31 CEST 2020
Block B Operation 2 End --> Thu Apr 9 21:21:31 CEST 2020
Block B Operation 1 End --> Thu Apr 9 21:21:32 CEST 2020
Block A: Operation 1 End --> Thu Apr 9 21:21:35 CEST 2020

I am expecting to start operations of Block B after that operations of Block A are completed.
The output that I was expecting is something like:

Block A: Operation 2 Start --> Thu Apr 9 21:21:27 CEST 2020
Block A: Operation 3 Start --> Thu Apr 9 21:21:27 CEST 2020
Block A: Operation 1 Start --> Thu Apr 9 21:21:27 CEST 2020
Block A: Operation 3 End --> Thu Apr 9 21:21:29 CEST 2020
Block A: Operation 2 End --> Thu Apr 9 21:21:31 CEST 2020
Block A: Operation 1 End --> Thu Apr 9 21:21:35 CEST 2020
Block B Operation 1 Start --> Thu Apr 9 21:21:27 CEST 2020
Block B Operation 2 Start --> Thu Apr 9 21:21:27 CEST 2020
Block B Operation 3 Start --> Thu Apr 9 21:21:27 CEST 2020
Block B Operation 3 End --> Thu Apr 9 21:21:28 CEST 2020
Block B Operation 2 End --> Thu Apr 9 21:21:31 CEST 2020
Block B Operation 1 End --> Thu Apr 9 21:21:32 CEST 2020

1 Answer 1

2

You have to use the asyncio module to create subprocesses, rather than the subprocess module directly.
From the docs:

import asyncio

async def run(cmd):
    proc = await asyncio.create_subprocess_shell(
        cmd,
        stdout=asyncio.subprocess.PIPE,
        stderr=asyncio.subprocess.PIPE)

    stdout, stderr = await proc.communicate()

    print(f'[{cmd!r} exited with {proc.returncode}]')
    if stdout:
        print(f'[stdout]\n{stdout.decode()}')
    if stderr:
        print(f'[stderr]\n{stderr.decode()}')

asyncio.run(run('ls /zzz'))
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.