Node.js에서 I/O는 대부분 libuv를 통해 처리된다.
libuv는 OS가 제공하는 비동기 I/O 기능을 추상화하고, OS별로 다른 이벤트 디멀티플렉서(epoll, kqueue, IOCP 등)를 사용한다.
여기서 FD는 다음 두 가지 경로에서 쓰인다:
예: TCP 소켓, 파이프, 일부 fs API, 타이머, 시그널 감시 등
JS 코드
↓
libuv → OS 이벤트 디멀티플렉서(epoll/kqueue/IOCP)
↓
FD 등록 (읽기/쓰기 가능 상태 감시)
↓
FD가 "ready" 상태가 되면 OS가 디멀티플렉서에 이벤트 알림
↓
libuv 이벤트 루프에서 해당 FD 이벤트 처리
↓
콜백 실행
예: fs.readFile(특정 플랫폼에서), crypto.pbkdf2, DNS lookup, 압축(zlib) 등
JS 코드
↓
libuv 스레드풀에 작업 요청
↓
워커 스레드에서 FD 사용해 블로킹 시스템 콜 수행
↓
작업 완료 후 결과를 libuv 메인 이벤트 루프의 pending queue에 넣음
↓
이벤트 루프가 해당 콜백 실행
libuv는 FD를 OS 이벤트 디멀티플렉서의 감시 대상 또는 스레드풀 시스템 콜의 파일 식별자로 활용하여, Node.js의 모든 비동기 I/O 동작을 통합적으로 관리한다.