[FastAPI] 동기와 비동기, 코루틴 개념 정리

2024. 3. 3. 23:41·Minding's Programming/FastAPI
목차
  1. 동기와 비동기
  2. 파이썬 코루틴
  3. 어웨이터블
728x90
반응형

FastAPI를 본격적으로 사용해보기에 앞서 알아보아야 할 개념인 동기와 비동기의 차이, 그리고 코루틴 함수에 대해서 공부해보았다.

 

동기와 비동기

- 동기(sync)

'코드가 동기적으로 동작한다'라는 말의 뜻은 '코드가 반드시 작성된 순서로 실행된다.'라는 뜻과 동일하다고 생각하면 된다. A,B,C의 순서로 코드가 작성되어 있다면, A 함수가 실행되고 끝나면 B가 실행되는 플로우로 진행된다.

import time


def delivery(name, mealtime):
    print(f"{name}에게 배달완료!")
    time.sleep(mealtime)  # n초 대기
    print(f"{name} 식사완료, {mealtime}시간 소요...")
    print(f"{name} 그릇 수거 완료")


def main():
    delivery("A", 3)
    delivery("B", 3)
    delivery("C", 4)


if __name__ == "__main__":
    start = time.time()  # 시작 시간(해당 시점 현재시간)
    main()
    end = time.time()  # 끝난 시간(현재시간)
    print(end - start)

 

- 비동기(async)

위와 반대로 '코드가 반드시 작성된 순서로 실행되는 것이 아니다.'라는 뜻이다. 함수 A가 실행되는 동안 B가 실행되었다가 종료될 수도 있다. 함수가 동시에 시작되지만, 각 함수의 처리 상황에 따라 종료 시점이 달라질 수 있다.

import time
import asyncio


async def delivery(name, mealtime):
    print(f"{name}에게 배달완료!")
    await asyncio.sleep(mealtime)  # n초 대기
    print(f"{name} 식사완료, {mealtime}시간 소요...")
    print(f"{name} 그릇 수거 완료")


async def main():
    await asyncio.gather(
        delivery("A", 5),
        delivery("B", 3),
        delivery("C", 4),
    )


if __name__ == "__main__":
    start = time.time()  # 시작 시간(해당 시점 현재시간)
    asyncio.run(main())
    end = time.time()  # 끝난 시간(현재시간)
    print(end - start)

 

위 설명만 읽으면, 비동기 함수로 코드를 작성하는 것이 무조건 좋을 것이라고 생각할 수도 있다. 하지만 비동기 함수를 사용할 때에도 사용 목적과 코드 흐름의 상황을 잘 파악해야 한다. 예를 들어 수학 계산식을 작동 시키는 간단한 함수라면, 굳이 비동기함수를 작성할 필요가 없다. 오히려 유지보수만 어려워지는 결과를 내기도 한다. 각 상황과 목적에 따라 비동기함수 사용여부를 잘 파악해야 한다.

 

 

파이썬 코루틴

- 메인 루틴: 프로그램이 진행되는 플로우 그 자체라고 할 수 있다. 코드 상의 "if __name__ == __main__" 이 부분이라고 할 수 있다.

- 서브 루틴: 메인 루틴에 포함되거나 각 함수에 포함되는 함수 그 자체들이다.

 

그렇다면 코루틴은 무엇일까?

- 코루틴의 특징

  • 다양한 진입점과 다양한 탈출점이 있다. (일반 루틴의 경우 하나의 진입점(호출)과 하나의 탈출점(return)만 있음)
  • ex) 짜장면 배달/수거 시스템 - A에게 짜장면을 배달 후 식사하는 동안 B에게 배달 후 다시 A의 그릇을 수거하러 감 = A 함수 진입 -> 탈출 -> B 함수 진입 -> 탈출 -> A 함수 진입(그릇 수거하는 부분으로 중간 진입)

 

위와 같은 코루틴을 사용하기 위해서는 asyncio라는 라이브러리를 사용해주어야 하며, 비동기 코루틴 함수를 지정할 때에는 함수 선언 앞에 async라고 붙여주어야 한다.

 

import asyncio
import time

async def say_after(delay, what):
    await asyncio.sleep(delay)
    print(what)

async def main():
    print(f"started at {time.strftime('%X')}")

    await say_after(1, 'hello')
    await say_after(2, 'world')

    print(f"finished at {time.strftime('%X')}")

asyncio.run(main())


>>>
started at 17:13:52
hello
world
finished at 17:13:55

위 코드는 await 이라는 표현식을 통해 코루틴 함수를 실행했다. 실행결과는 비동기 함수를 사용하지 않았을 때와 똑같을 것이다.

 

하지만 여러 개의 코루틴을 함수에 지정 예약하여(task1 등에 저장) 동시에 실행하는 asyncio.create_task() 함수를 사용한다면 차이가 생긴다.

async def main():
    task1 = asyncio.create_task(
        say_after(1, 'hello'))

    task2 = asyncio.create_task(
        say_after(2, 'world'))

    print(f"started at {time.strftime('%X')}")

    # Wait until both tasks are completed (should take
    # around 2 seconds.)
    await task1
    await task2

    print(f"finished at {time.strftime('%X')}")
    
    
>>>
started at 17:14:32
hello
world
finished at 17:14:34

이전 코드보다 1초 더 빠르게 실행이 완료된 모습을 볼 수 있다.

 

 

어웨이터블

하지만 모든 함수가 await 표현식으로 사용되는 것은 아니다. await 표현식에서 사용할 수 있는 '어웨이터블 객체'는 다음과 같다.

  • 코루틴 (async def 함수)
  • 태스크 (위에서 볼 수 있듯 asyncio.create_task()를 통해 코루틴을 예약해 놓은 함수)
  • 퓨처

해당 내용에 대한 자세한 설명은 Python 공식 문서를 통해 더 알아볼 수 있다. (아래 링크)

https://docs.python.org/ko/3/library/asyncio-task.html#coroutines

 

Coroutines and Tasks

This section outlines high-level asyncio APIs to work with coroutines and Tasks. Coroutines, Awaitables, Creating Tasks, Task Cancellation, Task Groups, Sleeping, Running Tasks Concurrently, Eager ...

docs.python.org

 

728x90

'Minding's Programming > FastAPI' 카테고리의 다른 글

[FastAPI/AWS/Uvicorn] AWS에 프로젝트 배포하기  (0) 2024.06.20
[FastAPI] 파이썬 멀티 프로세싱  (0) 2024.04.03
[FastAPI] 파이썬 멀티 스레딩 사용해보기  (0) 2024.04.01
[FastAPI] 동시성과 병렬성 개념 정리  (0) 2024.03.31
[FastAPI] FastAPI 특장, 설치 방법  (0) 2024.01.14
  1. 동기와 비동기
  2. 파이썬 코루틴
  3. 어웨이터블
'Minding's Programming/FastAPI' 카테고리의 다른 글
  • [FastAPI] 파이썬 멀티 프로세싱
  • [FastAPI] 파이썬 멀티 스레딩 사용해보기
  • [FastAPI] 동시성과 병렬성 개념 정리
  • [FastAPI] FastAPI 특장, 설치 방법
Minding
Minding
  • Minding
    Today's Minding
    Minding
  • 전체
    오늘
    어제
    • 울고넘는 딥러닝 (278)
      • Minding's Baseball (57)
        • MLB Statcast (29)
        • 머신러닝으로 홈런왕 예측하기 (3)
        • 야구칼럼 (12)
        • 야구 규칙, 용어 (1)
        • 2022-23 질롱 코리아 (8)
        • 류현진 등판경기 (4)
      • Minding's Programming (185)
        • 프로그래머스 코딩테스트 (21)
        • Knowledge (44)
        • Numpy & Pandas (6)
        • Excel (3)
        • Git (1)
        • Pygame (11)
        • CV (3)
        • Tensorflow tutorial (4)
        • Kaggle and Dacon (4)
        • 에러 코드 (8)
        • FastAPI (8)
        • Airflow (29)
        • Crawling (6)
        • Django (14)
        • AWS (18)
        • Spark (5)
      • Minding's Reading (30)
        • 머신러닝 딥러닝에 필요한 기초 수학 with 파이.. (2)
        • 칼만필터는 어렵지 않아 (11)
        • 밑바닥부터 시작하는 딥러닝 (6)
        • 메이저리그 야구 통계학 2e (8)
        • 논문읽기 (2)
        • 빅데이터를 지탱하는 기술 (1)
      • Minding's Life (5)
        • 주식 (4)
        • 각종 소식 (1)
  • 블로그 메뉴

    • 홈
    • Baseball
    • Programming
    • Reading
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    넘파이
    파이썬
    KBO
    데이터분석
    칼만필터
    Python
    칼만필터는어렵지않아
    AWS
    딥러닝
    칼만필터는어렵지않아python
    야구
    에어플로우
    Airflow
    파이썬게임개발
    머신러닝
    django
    데이터 엔지니어
    mlb stats api
    칼만필터는어렵지않아파이썬
    KalmanFilter
    게임개발
    pygame
    메이저리그
    django python
    프로그래머스
    파이게임
    FastAPI
    코딩테스트
    MLB
    질롱코리아
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
Minding
[FastAPI] 동기와 비동기, 코루틴 개념 정리

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.