카테고리 없음

[Multiprocessing] 큐와 파이프를 사용하여 여러 프로세스에서 결과를 받아오는 방법2 - asyncio 의 subprocess 이용

광장의꽃향기 2022. 7. 12. 16:06

https://rl-shampoo.tistory.com/9 에서 멀티프로세싱 프로그램을 만들었는데 subprocess 를 실행하는 부분이 syncronous 라 느렸다. async 하게 subprocess 를 실행할 방법이 없나 찾아봤더니 공식홈페이지에 내가 원하는 기능이 있는 듯해서 적용해보려한다.

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'))​

 

몇년전에도 asyncio 사용을 시도해본 적이 있었는데 loop 를 자기가 직접 만들어야 하고 코드의 어느곳에서나 loop 를 적용하는 것이 어려워보여 포기했었다. (이럴바에 그냥 multiprocessing 하지..)

그런데 몇년새 변한건지 위의 예시만 보면 javascript 에서의 promise 쓰는거랑 다를게 없단 생각이 들어 다시 시도해보고자 한다.

 

실수1.

asyncio.run() 은 한번만 호출할 수 있는듯하다. 아래와 같은 코드는 안된다.

async def run(cmd):
    await asyncio.sleep(1)
    

if __name__ == '__main__':
	for i in range(10):
    	asyncio.run(run("group 1.{}".format(i)))

 

아래처럼 바꿔줘야 한다.

async def main():

    group1 = asyncio.gather(*[run("group 1.{}".format(i)) for i in range(10)])
    await group1

if __name__ == '__main__':
    asyncio.run(main())