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())