libuv와 FD의 관계

Superhan·2025년 8월 10일

Node.js에서 I/O는 대부분 libuv를 통해 처리된다.
libuv는 OS가 제공하는 비동기 I/O 기능을 추상화하고, OS별로 다른 이벤트 디멀티플렉서(epoll, kqueue, IOCP 등)를 사용한다.

여기서 FD는 다음 두 가지 경로에서 쓰인다:

  1. 비차단(Non-blocking) I/O — 디멀티플렉서로 FD 등록
  2. 스레드풀 기반 I/O — FD를 OS 콜에서 직접 사용 후 결과 반환

1. 비차단 I/O 경로 (FD + 이벤트 디멀티플렉서)

예: TCP 소켓, 파이프, 일부 fs API, 타이머, 시그널 감시 등

JS 코드
   ↓
libuv → OS 이벤트 디멀티플렉서(epoll/kqueue/IOCP)
   ↓
FD 등록 (읽기/쓰기 가능 상태 감시)
   ↓
FD가 "ready" 상태가 되면 OS가 디멀티플렉서에 이벤트 알림
   ↓
libuv 이벤트 루프에서 해당 FD 이벤트 처리
   ↓
콜백 실행

💡 FD의 역할:

  • 디멀티플렉서가 "이 파일(소켓) 읽을 준비 됨" / "쓸 준비 됨"을 판단하는 키 값
  • libuv는 FD를 기반으로 이벤트 → 콜백 매핑을 관리

2. 스레드풀 기반 I/O 경로 (FD + worker thread)

예: fs.readFile(특정 플랫폼에서), crypto.pbkdf2, DNS lookup, 압축(zlib) 등

JS 코드
   ↓
libuv 스레드풀에 작업 요청
   ↓
워커 스레드에서 FD 사용해 블로킹 시스템 콜 수행
   ↓
작업 완료 후 결과를 libuv 메인 이벤트 루프의 pending queue에 넣음
   ↓
이벤트 루프가 해당 콜백 실행

💡 FD의 역할:

  • 워커 스레드가 실제 OS read() / write() / open() / close() 호출 시 대상 파일을 식별하는 값
  • 비동기처럼 보이지만, 내부적으로는 스레드에서 동기 실행 후 결과만 이벤트 루프에 전달

📌 정리 포인트

  • FD는 libuv 내부에서 "이벤트를 추적할 키"로 활용
    - 비차단 I/O → FD를 OS 디멀티플렉서에 등록
    - 스레드풀 I/O → FD를 시스템 콜 인자로 사용
  • libuv 이벤트 루프 단계
    1. timers
    2. pending callbacks
    3. idle, prepare
    4. poll (여기서 FD ready 이벤트 대기)
    5. check
    6. close callbacks

📍 한 줄 요약

libuv는 FD를 OS 이벤트 디멀티플렉서의 감시 대상 또는 스레드풀 시스템 콜의 파일 식별자로 활용하여, Node.js의 모든 비동기 I/O 동작을 통합적으로 관리한다.

참조 링크

profile
어디까지 알고, 어디까지 모를까?

0개의 댓글