비동기와 논블로킹의 근본적 차이
POSIX 명세에서 비동기 I/O와 논블로킹은 별개의 개념입니다. 논블로킹(Non-blocking)은 소켓이 요청한 작업을 즉시 완료할 수 없을 때 지연 없이 호출을 반환하는 소켓의 속성입니다. 반면 비동기 I/O는 I/O 작업이 백그라운드에서 실행되며 요청 스레드가 대기하지 않는 작업의 특성입니다. 논블로킹은 여러 소켓에 대해 폴링 루프가 필요하지만, 비동기는 콜백 또는 완료 알림 메커니즘을 통해 작업 완료를 통지합니다.
리눅스 커널의 구현 방식 비교
리눅스는 여러 비동기 I/O 구현을 제공합니다. POSIX AIO(aio_read, aio_write)는 glibc의 스레드 풀 기반이며 사용자 공간에서 구현되지만, 커널 네이티브 AIO(io_submit, io_getevents)는 2.6 커널부터 상태 머신 기반으로 동작합니다. io_uring(커널 5.1+)은 사용자 공간과 커널 간 공유 큐를 통해 배치 최적화를 제공합니다. 레거시 select()/poll()은 모든 소켓에 대한 폴링이 필요해 수백 개 이상의 동시 연결에서는 부적합합니다.
실무에서의 주의사항
논블로킹 I/O는 준비된 파일 디스크립터에 대해서만 유효하며, 단일 read()/write() 호출 후에도 더 이상 I/O를 수행할 수 없을 수 있습니다. 버퍼링된 파일 시스템 I/O에서는 논블로킹이 보장되지 않으므로 비동기 방식이 필수입니다. 또한 POSIX AIO의 스레드 풀 방식은 수천 개 연결 규모에서 확장성 문제를 야기하므로, 고성능 서버는 io_uring이나 epoll+논블로킹 조합을 선호합니다.