async/await의 설계 공간 탐색

3 hours ago 3

동시성 코드를 순차 코드처럼 작성하게 해주는 async/await는 언어마다 실행 의미가 달라, 같은 백그라운드 로그 예제가 7개 런타임에서 4가지 출력을 만듦 차이는 단순한 성능 문제가 아니라 관찰 가능한 동작을 바꾸는 설계 선택에서 발생하며, 연구는 이를 태스크의 시작·종료·취소에 걸친 9개 설계 차원으로 분류함 Swift와 Python+Trio는 태스크가 생성된 함수보다 오래 살지 못하게 하지만, 함수 종료 시 Swift는 태스크를 취소하고 Trio는 완료를 기다려 각각 AC와 ABC를 출력함 작은 비동기 프로그램도 정확히 이해하려면 호출의 즉시 실행 여부뿐 아니라 await의 중단 보장, 태스크 수명과 참조 강도, 예외 전파, 취소 방식까지 알아야 함 각 설계에는 성능·메모리·사용 편의성·실행 의미의 절충이 있어 유일한 정답은 없으며, 형식 의미론과 실행 추적으로 런타임별 결과가 갈리는 지점을 확인할 수 있음 순차 코드처럼 보이지만 실행 의미는 다른 async/await Python, Rust, Swift의 async/await는 공통적으로 동시성 프로그램을 순차 코드처럼 작성하도록 설계됨 이벤트 루프나 콜백을 사용하는 방식과 구별해 이 패러다임을 순차형 비동기성(straight-line asynchrony) 이라 부름 관련 언어 설계는 15년 이상 발전해 왔으며, 「A Design Space Exploration of Async/Await」 연구는 언어별 공통점과 차이를 탐색함 백그라운드 로그 하나가 만드는 네 가지 결과 예제의 write_to_log 는 A를 출력하고 await sleep(2)로 느린 로그 쓰기를 흉내 낸 뒤 B를 출력함 fire_and_forget은 spawn write_to_log()로 태스크를 만들고, 해당 태스크를 기다리지 않은 채 반환함 main은 fire_and_forget()을 기다린 뒤 await sleep(1)을 실행하고 C를 출력함 이 예제는 7개 런타임에서 4가지 출력을 만듦 Asyncio, C#, Tokio, Swift의 출력은 AC임 JavaScript는 ACB, Smol은 C, Trio는 ABC를 출력함 같은 프로그램의 세 가지 변형까지 비교하면, 7개 런타임 가운데 출력이 모두 같은 쌍은 하나도 없음 태스크 시작: 호출 시 실행과 await의 중단 보장 설계 차원은 순수한 성능 차이가 아니라 프로그램 실행의 관찰 가능한 의미를 바꾸는 선택임 즉시성(Eager...

Read Entire Article