비동기 코드는 컴퓨터가 다른 작업을 기다리는 동안, 그 시간에 다른 작업을 수행하는 방식으로 동작합니다. 비동기 함수 내부에서 await를 사용하여 해당 작업이 완료될 때까지 비동기적으로 대기할 수 있습니다.
다음과 같은 코드에서 await를 사용하는 경우:
results = await some_library()
async def를 사용하여 경로 작동 함수를 선언하세요:
@app.get('/')
async def read_results():
results = await some_library()
return results
async def로 선언된 함수 내부에서만 await를 사용할 수 있습니다.만약, 제3의 라이브러리가 await를 지원하지 않는다면, def를 사용하여 일반적인 함수로 선언해야 합니다:
@app.get('/')
def results():
results = some_library()
return results
FastAPI는 일반적인 def와 async def를 혼용할 수 있고, 시스템 성능을 최적화하기 위해 올바르게 처리됩니다.
비동기 코드는 언어가 다른 작업의 완료를 기다리며 실행을 일시정지하는 방식으로 작동합니다. 이는 느린 작업이 완료될 때까지 기다리며, 다른 작업을 처리할 수 있는 기회를 제공합니다.
비동기 시스템은 작업이 완료될 때까지 기다릴 필요 없이, 다른 작업을 처리할 수 있습니다. 컴퓨터는 그동안 다른 요청을 처리하거나, 자원을 활용해 작업을 처리하고, 작업이 끝나면 그 결과를 받아 다시 돌아옵니다.
동시성과 병렬성은 둘 다 동시에 여러 작업을 처리하는 방식과 관련이 있습니다. 그러나 두 개념은 본질적으로 다릅니다:
<동시 버거>
당신은 짝사랑 상대😍와 패스트푸드🍔를 먹으러 갔습니다. 당신은 점원💁이 당신 앞에 있는 사람들의 주문을 받을 동안 줄을 서서 기다리고 있습니다.
이제 당신의 순서가 되어서, 당신은 당신과 짝사랑 상대😍를 위한 두 개의 고급스러운 버거🍔를 주문합니다.
당신이 돈을 냅니다 💸.
점원 💁 은 주방 👨🍳 에 요리를 하라고 전달하고, 따라서 그들은 당신의 버거 🍔 를 준비해야한다는 사실을 알게됩니다(그들이 지금은 당신 앞 고객들의 주문을 준비하고 있을지라도 말입니다).
점원 💁 은 당신의 순서가 적힌 번호표를 줍니다.
기다리는 동안, 당신은 짝사랑 상대 😍 와 함께 테이블을 고르고, 자리에 앉아 오랫동안 (당신이 주문한 버거는 꽤나 고급스럽기 때문에 준비하는데 시간이 조금 걸립니다 ✨🍔✨) 대화를 나눕니다.
짝사랑 상대 😍 와 테이블에 앉아서 버거 🍔 를 기다리는 동안, 그 사람 😍 이 얼마나 멋지고, 사랑스럽고, 똑똑한지 감탄하며 시간을 보냅니다 ✨😍✨.
짝사랑 상대 😍 와 기다리면서 얘기하는 동안, 때때로, 당신은 당신의 차례가 되었는지 보기 위해 카운터의 번호를 확인합니다.
그러다 어느 순간, 당신의 차례가 됩니다. 카운터에 가서, 버거 🍔 를 받고, 테이블로 다시 돌아옵니다.
당신과 짝사랑 상대 😍 는 버거 🍔 를 먹으며 좋은 시간을 보냅니다 ✨.
당신이 이 이야기에서 컴퓨터 / 프로그램 🤖 이라고 상상해보십시오.
줄을 서서 기다리는 동안, 당신은 아무것도 하지 않고 😴 당신의 차례를 기다리며, 어떠한 "생산적인" 일도 하지 않습니다. 하지만 점원 💁 이 (음식을 준비하지는 않고) 주문을 받기만 하기 때문에 줄이 빨리 줄어들어서 괜찮습니다.
그다음, 당신이 차례가 오면, 당신은 실제로 "생산적인" 일 🤓 을 합니다. 당신은 메뉴를 보고, 무엇을 먹을지 결정하고, 짝사랑 상대 😍 의 선택을 묻고, 돈을 내고 💸 , 맞는 카드를 냈는지 확인하고, 비용이 제대로 지불되었는지 확인하고, 주문이 제대로 들어갔는지 확인을 하는 작업 등등을 수행합니다.
하지만 이후에는, 버거 🍔 를 아직 받지 못했음에도, 버거가 준비될 때까지 기다려야 🕙 하기 때문에 점원 💁 과의 작업은 "일시정지" ⏸ 상태입니다.
하지만 번호표를 받고 카운터에서 나와 테이블에 앉으면, 당신은 짝사랑 상대 😍 와 그 "작업" ⏯ 🤓 에 번갈아가며 🔀 집중합니다. 그러면 당신은 다시 짝사랑 상대 😍 에게 작업을 거는 매우 "생산적인" 일 🤓 을 합니다.
점원 💁 이 카운터 화면에 당신의 번호를 표시함으로써 "버거 🍔 가 준비되었습니다"라고 해도, 당신은 즉시 뛰쳐나가지는 않을 것입니다. 당신은 당신의 번호를 갖고있고, 다른 사람들은 그들의 번호를 갖고있기 때문에, 아무도 당신의 버거 🍔 를 훔쳐가지 않는다는 사실을 알기 때문입니다.
그래서 당신은 짝사랑 상대 😍 가 이야기를 끝낼 때까지 기다린 후 (현재 작업 완료 ⏯ / 진행 중인 작업 처리 🤓 ), 정중하게 미소짓고 버거를 가지러 가겠다고 말합니다 ⏸.
그다음 당신은 카운터에 가서 🔀 , 초기 작업을 이제 완료하고 ⏯ , 버거 🍔 를 받고, 감사하다고 말하고 테이블로 가져옵니다. 이로써 카운터와의 상호작용 단계 / 작업이 종료됩니다 ⏹.
이전 작업인 "버거 받기"가 종료되면 ⏹ "버거 먹기"라는 새로운 작업이 생성됩니다 🔀 ⏯.
동시성 버거 가게 시나리오:
<병렬 버거¶>
이제 "동시 버거"가 아닌 "병렬 버거"를 상상해보십시오.
당신은 짝사랑 상대 😍 와 함께 병렬 패스트푸드 🍔 를 먹으러 갔습니다.
당신은 여러명(8명이라고 가정합니다)의 점원이 당신 앞 사람들의 주문을 받으며 동시에 요리 👩🍳👨🍳👩🍳👨🍳👩🍳👨🍳👩🍳👨🍳 도 하는 동안 줄을 서서 기다립니다.
당신 앞 모든 사람들이 버거가 준비될 때까지 카운터에서 떠나지 않고 기다립니다 🕙 . 왜냐하면 8명의 직원들이 다음 주문을 받기 전에 버거를 준비하러 가기 때문입니다.
마침내 당신의 차례가 왔고, 당신은 당신과 짝사랑 상대 😍 를 위한 두 개의 고급스러운 버거 🍔 를 주문합니다.
당신이 비용을 지불합니다 💸 .
점원이 주방에 갑니다 👨🍳 .
당신은 번호표가 없기 때문에 누구도 당신의 버거 🍔 를 대신 가져갈 수 없도록 카운터에 서서 기다립니다 🕙 .
당신과 짝사랑 상대 😍 는 다른 사람이 새치기해서 버거를 가져가지 못하게 하느라 바쁘기 때문에 🕙 , 짝사랑 상대에게 주의를 기울일 수 없습니다 😞 .
이것은 "동기" 작업이고, 당신은 점원/요리사 👨🍳 와 "동기화" 되었습니다. 당신은 기다리고 🕙 , 점원/요리사 👨🍳 가 버거 🍔 준비를 완료한 후 당신에게 주거나, 누군가가 그것을 가져가는 그 순간에 그 곳에 있어야합니다.
카운터 앞에서 오랫동안 기다린 후에 🕙 , 점원/요리사 👨🍳 가 당신의 버거 🍔 를 가지고 돌아옵니다.
당신은 버거를 받고 짝사랑 상대와 함께 테이블로 돌아옵니다.
단지 먹기만 하다가, 다 먹었습니다 🍔 ⏹.
카운터 앞에서 기다리면서 🕙 너무 많은 시간을 허비했기 때문에 대화를 하거나 작업을 걸 시간이 거의 없었습니다 😞 .
병렬 버거 가게 시나리오:
FastAPI를 사용하면 웹 개발에서는 매우 흔한 동시성의 이점을 얻을 수 있다.
머신러닝 시스템과 같이 CPU에 묶인 작업을 위해 병렬성과 멀티프로세싱(다수의 프로세스를 병렬적으로 동작시키는 것)을 이용하는 것도 가능합니다.
파이썬이 데이터 사이언스, 머신러닝과 특히 딥러닝에 의 주된 언어라는 간단한 사실에 더해서, 이것은 FastAPI를 데이터 사이언스 / 머신러닝 웹 API와 응용프로그램에 (다른 것들보다) 좋은 선택지가 되게 한다.
최신 파이썬은 async def를 사용하여 비동기 작업을 처리할 수 있습니다. async def 함수 내부에서는 await 키워드를 사용해 특정 작업이 완료될 때까지 대기할 수 있습니다.
async def get_burgers(number: int):
return await some_async_function(number)
위 예시에서 await 키워드는 some_async_function() 작업이 완료될 때까지 기다리라고 명령하는 것입니다.
async def로 선언된 함수는 비동기적으로 처리되며, 함수 내에서 await 키워드를 사용해 대기 작업을 처리합니다.
@app.get('/burgers')
async def read_burgers():
burgers = await get_burgers(2)
return burgers
여기서 FastAPI는 async def를 이용해 대기 작업을 최적화하여 처리할 수 있으며, 이를 통해 웹 애플리케이션에서 높은 성능을 제공합니다.
코루틴은 async def 함수가 반환하는 것을 칭하는 매우 고급스러운 용어일 뿐이다.
파이썬은 그것이 시작되고 어느 시점에서 완료되지만 내부에 await가 있을 때마다 내부적으로 일시정지⏸될 수도 있는 함수와 유사한 것이라는 사실을 알고있다.
그러나 async 및 await와 함께 비동기 코드를 사용하는 이 모든 기능들은 "코루틴"으로 간단히 요약됩니다. 이것은 Go의 주된 핵심 기능인 "고루틴"에 견줄 수 있다.
FastAPI는 비동기 웹 애플리케이션 개발에서 동시성과 병렬성을 모두 지원합니다. FastAPI를 사용하면 비동기 시스템의 이점을 활용해 매우 빠른 응답 속도를 얻을 수 있습니다.
또한, 병렬성과 비동기성을 동시에 사용할 수 있기 때문에 CPU에 묶인 작업(예: 이미지 처리, 머신러닝 모델 실행 등)도 효과적으로 처리할 수 있습니다.