Libuv:Design
libuv는 Node.js를 위해 작성된 크로스 플랫폼 라이브러리 이다. 이것은 이벤트 기반 비동기 I/O 모델을 중심으로 설계되었다. 여러 I/O 폴링 메커니즘을 위에서 간단한 추상화를 제공한다.
Handles and requests
libuv는 이벤트 루프와 두 개의 추상화 객체의 조합으로 제공된다.
- Handle
- Request
The I/O loop
libuv Loop iteration I/O Loop (or Event loop)는 libuv의 중심부이다. 모든 I/O 동작을 위한 내용을 설정하고, 하나의 스레드에 연결되는 것을 의미하다.
경고 |
여러 이벤트 루프(Multiple event loops)는 각각 다른 스레드에서 실행되며, 이벤트 루프는 특별히 명시하지 않는 한 스레드에 안정하지 않다. 1 |
Event-loop는 일반적인 단일 스레드 비동기 I/O 방법을 사용한다. 모든 (Network) I/O의 Non-blocking socket 폴링은 주어진 플랫폼에서 사용할 수 있는 최적의 메커니즘을 사용한다.
- epoll on Linux
- kqueue on OSX and other BSDs
- event ports on SunOS
- IOCP on Windows.
아래 순서로 루프가 진행된다.
- 업데이트가 이루어진다. 시스템 콜 횟수 감소를 위해 현재 시간을 저장한다.
- LOOP가 살아있지 않다면 즉시 종료한다. LOOP가 살아있는 경우란, Reference handle이 활성화 됐거나, 활성화 요청, 닫는중(Closing handle)일 경우이다. 2
- Due timers are run.
- 대기중인 콜백이 호출된다. 모든 I/O 콜백은 I/O 폴링 이후에 호출된다. 다음 루프에 대한 지연이 필요하다면 이 시점에 실행된다. 직전 Iteration이 지연된 경우 모든 I/O 콜백은 이 시점에 호출된다.
- 대기 핸들 콜백 (Idle handle callbacks)을 호출한다.
- Prepare handle callbacks are called.
- Poll Timeout을 계산한다. 아래는 Timeout을 계산하는 규칙이다:
- If the loop was run with the
UV_RUN_NOWAIT
flag, the timeout is 0. - If the loop is going to be stopped (
uv_stop()
was called), the timeout is 0. - If there are no active handles or requests, the timeout is 0.
- If there are any idle handles active, the timeout is 0.
- If there are any handles pending to be closed, the timeout is 0.
- If none of the above cases was matched, the timeout of the closest timer is taken, or if there are no active timers, infinity.
- If the loop was run with the
- The loop blocks for I/O.
- Check handle callbacks are called.
- Close callbacks are called.
- Special case in case the loop was run with
UV_RUN_ONCE
, as it implies forward progress. - Iteration ends.
Important |
libuv에서는 I/O 작업 가능한 비동기 파일을 만들기 위해 스레드 풀을 사용하지만, 네트워크 I/O는 항상 단일 스레드로 동작한다. |