sync와 async의 차이는 무엇일까
동기적 코드 (Synchronous code)란?
일반적으로 작성하는 코드는 동기적인 코드다.
그럼 동기적인 코드는 무엇인가
- 순차적인 실행
- Blocking 기반 실행
이렇게 2가지 특징을 가진 코드라 볼수있다.
순차적 실행이란 코드작성 순서대로 위에서 아래로 실행 된다는 의미이며 위의 코드가 실행이 완료되어야 밑에 코드가 실행된단 의미다.
blocking이란 코드에서 함수가 작업에 들어갈 때 기존 코드의 흐름(thread)은 정지되고 함수내부의 흐름(thread)으로 진행되게 끔하는 방식이다.
예시 코드1) 동기적 코드이자 blocking 코드
결과 코드 1)
코드 해석
예시 코드1) 의 경우 main 블록에서 코드의 순차대로(Sequential) world 함수가 실행되고 print 문이 실행되는 것을 볼 수 있다.
그럼 동기적코드의 특징 중 Blocking 기반 실행이란 무엇일까?
예시코드1) 에는 총 2가지 의 블록(block)이 있다.
- 메인 함수 블록
-
if __name__ == "__main__":world ()
- 함수 블록
def main():print("hellow world")
부분에서 처음으로 코드가 작동하기 시작한다
이때 현재 파일이 main 인지 확인하고 메인일 경우
위에 선언한 함수가 실행된다.
이때 if __name__ == "__main__": 에 있던 흐름은 def world(): 블록 으로 넘어간다.
그 후 def world (): 을 완료한 뒤 흐름은 다시 if __name__ == "__main__": 블록으로 돌아온다.
그리고 나머지 if __name__ == "__main__": 의 코드 print("bye world") 를 실행하고 코드는 완료된다.
여기서
wolrd 함수를 실행하는 도중 메인 블록(위의 코드 부분)은 진행을 멈추게 된다.
이를 Blocking 이라하며 위의 코드는 sync Blocking 방식으로 작동한 것이 된다.
비동기적 코드 (asynchronous code)란?
코드가 동시에 (Concurrency)에 그리고 독립적으로 실행되는 코드를 뜻한다
병렬성(Parallelism)과는 다르다! 병렬성(Parallelism)이랑은...
비동기적 코드의 예
우리가 게임을 할 때 채팅을 친다고 게임이 멈추지 않는다.
비동기적 코드의 특징은 동기적 코드와 반대라고 보면된다
- 독립적, 동시적 실행
- non-blocking 기반 실행
비동기적 코드는 분명 non-blocking을 기반으로 작동하게 하는 것이 거의 대부분의 존재 이유다.
하지만 비동기 코드를 잘 못다루는 경우 비동기 non-blocking이라 착각을 하고 비동기 blocking 코드를 만드는 경우가 많다.
분명 비동기 코드지만 blocking으로 작동하는 코드는 마치 동기적인 코딩 결과를 보여주게 된다.
비동기적 코드를 이해하기 위해선 coroutine의 개념을 이해해야한다.
python에서는 3.5버전 부터 async와 await를 지원한다.
그 아래 버전은 @asyncio.coroutine 데코레이터를 이용해야 한다.
async blocking vs asunc non-blocking
blocking 예시코드)
blocking 예시코드 결과)
왤까 분명 async await를 이용하여 비동기를 구현 했으나 결과가 이상하다.
예측상으로 4초안에 다 끝나야 하는데 그렇지 않다.
이유는 blocking이다.
처음 비동기를 쓰는 사람들이 착각하기 쉬운 파이썬 문법이다 async와 await를 쓰면 무조건 비동기 non-block으로 작동하는 것으로 착각한다.
await는 for ~ in ~ 같이 비동기 함수를 실행하는 덩어리가 아니다.
await는 함수의 결과를 기다리라는 키워드다
위 코드는 정성스레 비동기로 만들었으나 정작 동기로 작동된다. 그럼 어떻게 해결해야 할까?
non-blocking 예시코드)
non-blocking 예시코드 결과)
드디어 4초만에 모든 코드가 끝났다.
게다가 task1은 4초를 기다리느라 결과가 task2보다 늦게 나왔다.
non-blocking이란 이런것이다. 메인 블록이 다른 블록이 돌아가던 말던 끊임없이 돌아간다.
그럼 여기서 왜 이번엔 제대로 되었을까?
그건 task 객체를 이용해 scheduling을 했기 때문이다.
https://docs.python.org/3/library/asyncio-task.html
비동기를 제대로 하기 위해선 Task, Future, schedule, coroutine, thread, Event Loop 등 다양한 이론을 알아야 한다.
이번 글에서는 동기와 비동기가 무엇인지 코드를 통해 예시를 보여줬다. 다음 글에선 비동기를 깊고 자세히 파보도록 하겠다.
'python' 카테고리의 다른 글
[FastAPI] restapi를 위한 코드 순서 (0) | 2024.09.26 |
---|---|
poetry add 혹은 pipenv install 무한로딩 (0) | 2024.05.08 |
class 적응하기 2 (0) | 2024.01.30 |
class 적응하기 1 (0) | 2024.01.30 |
Class method vs Static method in python (2) | 2024.01.03 |