멀티플랫폼을 지원하는 c 라이브러리 이다.
이벤트 루프를 기반으로 비동기 I/O 처리를 기능을 제공하고 있다.
Nodejs 에서 사용 하도록 개발 되었지만, 다른 소프트웨어에서도 사용되고 있는 중이다.
(예: Node.js, Luvit, Julia, uvloop)
epoll (Linux)
:확장 가능한 I/O 이벤트 노티피케이션 메커니즘을 위한 리눅스 커널 시스템 호출.
I/O가 가능한지 여부를 확인하기 위해 여러 fd(파일 설명자)를 모니터링.
현재 모니터링되고 있는 모든 파일 설명자를 추적하기 위해 RB-트리(red-black tree) 데이터 구조를 사용.
kqueue (Unix, OSX)
:확장 가능한 이벤트 알림 인터페이스. 여러 UNIX 환경에서 사용 되고 있음. Kqueue를 사용하는 nginx와 같은 소프트웨어가 c10k(문제는 동시에 많은 수의 클라이언트를 처리하도록 네트워크 소켓을 최적화하는 문제 Connection 10K - 10,000) 문제를 해결함.
IOCP(Input/output completion port) (Window, Solaris)
:여러 동시 비동기 입/출력 작업을 수행하기 위한 API.
IOCP 개체가 생성되고 다수의 소켓 또는 파일 핸들과 연결.
I/O 요청의 상태를 확인하기 위해 IOCP의 메시지 대기열을 확인.
IOCP는 여러 스레드와 해당 동시성을 관리.
event prots (Solaris)
:이벤트 포트는 응용 프로그램이 연결되지 않은 소스에서 이벤트를 생성하고 수집할 수 있도록 하는 프레임워크. 프레임워크는 전체 성능을 저하시키지 않고 동시에 여러 개체에서 이벤트를 검색 가능.
DNS resolution
:IP 주소를 도메인 이름으로 변환하는 프로세스
ANSI escape code
:ANSI 이스케이프 시퀀스 는 비디오 텍스트 터미널 및 터미널 에뮬레이터 의 커서 위치, 색상, 글꼴 스타일 및 기타 옵션을 제어하기 위한 대역 내 신호 의 표준입니다 . ASCII 이스케이프 문자와 대괄호 문자 로 시작하는 특정 바이트 시퀀스는 텍스트에 포함됩니다. 터미널은 이러한 시퀀스를 텍스트가 아닌 명령으로 해석하여 그대로 표시합니다.
libuv는 원래 Node.js 용으로 작성된 크로스 플랫폼 지원 라이브러리이고, 이벤트 기반 비동기 I/O 모델을 중심으로 설계되었다.
라이브러리는 다양한 I/O 폴링 메커니즘에 대한 단순한 추상화 이상의 것을 제공한다. 무엇보다도 크로스 플랫폼 파일 I/O 및 스레딩 기능도 제공된다.
handle, requests
libuv는 사용자에게 이벤트 루프와 함께 작업할 2가지 추상화(handle 및 reqeusts)를 제공.
handle
:수명이 긴 특정 작업을 나타냄. (예: 준비 핸들은 활성 상태일 때 루프 반복마다 한 번 호출되는 콜백을 가져옴)
requests
: 단기 작업을 나타냅니다. 핸들을 통해 이러한 작업을 수행. 쓰기 요청은 핸들에 데이터를 쓰는 데 사용. 또는 독립 실행형: getaddrinfo 요청은 루프에서 직접 실행되는 핸들이 필요않음.
The I/O Loop
I/O(또는 이벤트) 루프는 libuv의 중심 부분임.
모든 I/O 작업에 대한 내용을 설정하고 단일 스레드에 연결됨.
각각이 다른 스레드에서 실행되는 한 여러 이벤트 루프를 실행. libuv 이벤트 루프(또는 루프나 핸들과 관련된 다른 API) 는 달리 명시된 경우를 제외하고는 not thread safety
thread safety
:여러 쓰레드가 데이터에 액세스할때에 구현에 경쟁조건이 없음을 보장.
*중요: libuv는 스레드 풀을 사용하여 비동기 파일 I/O 작업을 가능하게 하지만 네트워크 I/O는 항상 각 루프의 스레드인 단일 스레드에서 수행.
이벤트 루프는 가능하다면 언제나 시스템 커널에 작업을 떠넘겨서 Node.js가 논 블로킹 I/O 작업을 수행하도록 해줍니다.(JavaScript가 싱글 스레드임에도 불구하고)
대부분의 현대 커널은 멀티 스레드이므로 백그라운드에서 다수의 작업을 실행할 수 있습니다. 이러한 작업 중 하나가 완료되면 커널이 Node.js에게 알려주어 적절한 콜백을 poll 큐에 추가할 수 있게 하여 결국 실행되게 합니다. 이 글 후반부에서 더 자세한 내용을 설명할 것입니다.
timers: 이 단계는 setTimeout()과 setInterval()로 스케줄링한 콜백을 실행.
pending callbacks: 다음 루프 반복으로 연기된 I/O 콜백들을 실행.
idle, prepare: 내부용으로만 사용합니다.
poll: 새로운 I/O 이벤트를 가져옵니다. I/O와 연관된 콜백(클로즈 콜백, 타이머로 스케줄링된 콜백, setImmediate()를 제외한 거의 모든 콜백)을 실행합니다. 적절한 시기에 node는 여기서 블록 합니다.
check: setImmediate() 콜백은 호출.
close callbacks: 일부 close 콜백들, (예: socket.on('close', ...))
process.nextTick()이 비동기 API에 속해있지만, 다이어그램에는 표시되지 않은 것을 눈치챘을 겁니다. 이는 process.nextTick()이 기술적으로는 이벤트 루프의 일부가 아니기 때문입니다. 대신 nextTickQueue는 이벤트 루프의 현재 단계와 관계없이 현재 작업이 완료된 후에 처리될 것입니다.