Zig의 새로운 비동기 프로그램 설계

6 days ago 4

  • Zig 언어가 기존 비동기 I/O 설계의 복잡성을 줄이기 위해 새로운 Io 인터페이스 기반 모델을 도입
  • 이 모델은 동기·비동기 코드의 구분 없이 동일한 함수 구조를 유지하며, Io.Threaded와 Io.Evented 두 구현을 제공
  • Io.Threaded는 기본적으로 동기 실행을, Io.Evented는 이벤트 루프 기반 비동기 실행을 수행
  • 개발자는 async()와 concurrent() 함수를 통해 병렬 실행 제어가 가능하며, 코드 수정 없이 성능 최적화 가능
  • 이 접근은 함수 색칠(function coloring) 문제를 해결하고, Zig의 단순성과 제어성을 유지한 채 비동기 성능을 확보하는 방향

Zig의 비동기 설계 변화

  • Zig는 기존 비동기 설계가 언어의 미니멀리즘 철학과 잘 맞지 않아 새로운 접근을 모색
    • 기존 설계는 다른 기능과의 통합성이 낮았음
    • 새 모델은 동기·비동기 I/O를 동일한 코드 구조로 처리 가능
  • 새로운 설계는 Io 제너릭 인터페이스를 중심으로 동작
    • 모든 I/O 함수는 Io 인스턴스를 매개변수로 받아 실행
    • Allocator 인터페이스와 유사한 구조로, 메모리 할당과 같은 방식으로 I/O 제어 가능

Io 인터페이스의 구조

  • 표준 라이브러리에 두 가지 기본 구현체 포함
    • Io.Threaded : 기본적으로 동기 실행, 필요 시 스레드 병렬 처리
    • Io.Evented : 이벤트 루프 기반 비동기 실행 (io_uring, kqueue 등 사용)
  • 사용자는 직접 새로운 Io 구현체를 작성할 수 있어, 실행 방식에 대한 세밀한 제어 가능

코드 예시와 동작 방식

  • 예시 함수 saveFile()은 파일 생성, 쓰기, 닫기를 수행
    • Io.Threaded 사용 시 일반 시스템 호출로 동작
    • Io.Evented 사용 시 비동기 백엔드로 실행
    • 두 경우 모두 writeAll() 호출 시점에 작업 완료 보장
  • 동일한 코드가 동기·비동기 환경 모두에서 동일하게 작동
    • 라이브러리 작성자는 실행 방식에 신경 쓸 필요 없음

병렬 실행과 async() / concurrent()

  • async() 함수는 비동기 실행을 요청하지만, Io.Threaded에서는 즉시 실행될 수도 있음
    • Io.Evented에서는 실제 비동기 실행으로 두 파일을 동시에 저장 가능
  • concurrent() 함수는 실제 병렬 실행이 필요한 경우 사용
    • Io.Threaded는 스레드 풀을 활용
    • Io.Evented는 async()와 동일하게 처리
  • 잘못된 함수 선택(async 대신 concurrent)은 버그로 간주, 언어 차원에서 방지 불가

코드 스타일과 언어 통합

  • 비동기 전용 문법 없이 일반 Zig 코드 스타일 유지
    • try, defer 등 기존 제어 흐름 문법 그대로 사용
    • Andrew Kelley는 “표준 Zig 코드처럼 읽힌다”고 언급
  • 예시로 비동기 DNS 조회 구현 제시
    • getaddrinfo()와 달리 첫 번째 성공 응답만 반환하고 나머지 요청은 취소

향후 계획과 개발 현황

  • Io.Evented는 아직 실험적 단계, 일부 OS 미지원
  • WebAssembly 호환 Io 구현이 계획 중이며, 관련 기능 개발 필요
  • Io 관련 24개의 후속 작업 항목이 존재하며 대부분 미완료 상태
  • Zig는 아직 1.0 버전 전으로, 비동기 I/O와 네이티브 코드 생성이 주요 남은 과제
  • 이번 설계로 I/O 인터페이스 변경으로 인한 코드 재작성 빈도 감소 기대

커뮤니티 논의 요약

  • 여러 댓글에서 Zig의 접근이 Rust의 async/await 모델보다 단순하고 유연하다는 평가
    • Rust는 여러 executor 혼용 시 복잡성이 높음
    • Zig는 Io 인터페이스로 다중 executor 공존 가능성 확보
  • 일부는 코드가 다소 장황해질 수 있음을 지적
    • 그러나 명시적 API 설계로 보안·성능·테스트 제어성 향상
  • 비동기 실행과 스레드 실행의 차이, stackful vs stackless coroutine 구현 방식 등 기술적 논의도 이어짐
  • Zig의 Io는 언어 차원의 특별한 처리 없이 표준 라이브러리 확장 형태로 구현됨
    • 향후 stackless coroutine 기능이 추가될 예정

결론

  • Zig의 새 비동기 모델은 언어 단순성 유지와 고성능 I/O 양립을 목표로 함
  • 함수 색칠 문제 해결, 동기·비동기 코드 통합, 명시적 제어 구조를 통해
    Zig 1.0 안정화의 핵심 단계로 평가됨

Read Entire Article