반응형
asyncio
는 한 개의 쓰레드에서 돌아가지만, 동시성이 존재한다. 이 때문에, 잘 못 쓰면 작업들이 예상치 못한 순서로 일어날 수도 있다.threading
이나multiprocessing
에서와 같은 Lock을 사용하면 예기치 못한 상황을 예방할 수 있다. (save concurrency)
Example
Without Lock
import asyncio
import random
owner = None
async def coro1():
global owner
owner = 'IAMMAN'
print(f"I am owner, {owner}")
await asyncio.sleep(random.random())
print(f"{owner} is man.")
async def coro2():
global owner
owner = 'IAMWOMAN'
print(f"I am owner, {owner}")
await asyncio.sleep(random.random())
print(f"{owner} is woman.")
async def main(loop):
while True:
await asyncio.gather(coro1(), coro2())
await asyncio.sleep(0.1)
if __name__ == "__main__":
event_loop = asyncio.get_event_loop()
try:
event_loop.run_until_complete(main(event_loop))
finally:
event_loop.close()
Result
I am owner, IAMMAN
I am owner, IAMWOMAN
IAMWOMAN is woman.
IAMWOMAN is man.
I am owner, IAMMAN
I am owner, IAMWOMAN
IAMWOMAN is woman.
IAMWOMAN is man.
I am owner, IAMMAN
I am owner, IAMWOMAN
IAMWOMAN is man.
IAMWOMAN is woman.
...
→ 보는것 처럼 마구잡이로 섞여있다.
With Lock
import asyncio
import random
owner = None
async def coro1(lock):
global owner
await lock.acquire()
owner = 'IAMMAN'
print(f"I am owner, {owner}")
await asyncio.sleep(random.random())
print(f"{owner} is man.")
lock.release()
async def coro2(lock):
global owner
async with lock:
owner = 'IAMWOMAN'
print(f"I am owner, {owner}")
await asyncio.sleep(random.random())
print(f"{owner} is woman.")
async def main(loop):
lock = asyncio.Lock()
while True:
await asyncio.gather(coro1(lock), coro2(lock))
await asyncio.sleep(0.1)
if __name__ == "__main__":
event_loop = asyncio.get_event_loop()
try:
event_loop.run_until_complete(main(event_loop))
finally:
event_loop.close()
결과
I am owner, IAMMAN
IAMMAN is man.
I am owner, IAMWOMAN
IAMWOMAN is woman.
I am owner, IAMMAN
IAMMAN is man.
I am owner, IAMWOMAN
IAMWOMAN is woman.
I am owner, IAMMAN
IAMMAN is man.
I am owner, IAMWOMAN
IAMWOMAN is woman.
I am owner, IAMMAN
→ 의도했던 결과가 나온다.
- 위의 예제만 보면 이럴거면 굳이 왜 비동기로 짜냐고 생각할 수 있지만, 복잡한 코드 속에서 필요한 부분만 적재적소에
Lock
을 사용해주면 더욱 안정성있는 프로그램을 만들 수 있다.
반응형
'개발 > 파이썬' 카테고리의 다른 글
파이썬에서 arguments로 *(별표)만 쓴 경우!? (0) | 2019.07.29 |
---|---|
파이썬 3.7부터 도입된 dataclasses에 대해 알아보자 (0) | 2019.07.26 |
[TIL] 파이썬 3.7 asyncio High API (0) | 2019.07.20 |
[TIL] 파이썬 typing 모듈을 사용할 때 Import Error가 나는 경우 (0) | 2019.05.17 |
[TIL] JWT 토큰 쿠키에 저장하기 (Flask) (0) | 2019.05.05 |