Skip to main content

libuv та його роль

1. Що таке libuv

libuv - це крос-платформна бібліотека на C, створена спеціально для Node.js. Вона реалізує:

  • Event Loop (цикл подій);
  • асинхронний I/O (введення-виведення без блокувань);
  • пул потоків (Thread Pool) для фонових задач;
  • таймери, черги й системні події.

Спочатку вона була створена для Node.js, але тепер використовується і в інших проєктах (наприклад, Luvit, Julia).

2. Event Loop - головний цикл подій

libuv реалізує Event Loop, який керує порядком виконання задач:

Спрощена модель:

  1. V8 виконує синхронний код.
  2. Коли зустрічає асинхронну операцію (наприклад, fs.readFile або setTimeout), Node.js передає її libuv.
  3. libuv поміщає задачу в чергу подій.
  4. Коли результат готовий (файл прочитано, таймер спрацював, з'єднання встановлено), libuv ставить callback назад у чергу Event Loop.
  5. V8 виконує callback, коли до нього доходить черга.

Отже, Event Loop дозволяє Node.js бути однопоточним на рівні JS, але багатопоточним під капотом.

3. Thread Pool - пул потоків

Хоча JS-код виконується в одному потоці, деякі операції виконуються у фоні:

  • операції з файловою системою (fs),
  • DNS-запити,
  • криптографічні операції (crypto.pbkdf2, scrypt),
  • стиснення (zlib).

libuv використовує пул із 4 потоків (за замовчуванням) для їх виконання. Ти можеш збільшити це число за допомогою змінної середовища:

javascript
UV_THREADPOOL_SIZE=8 node app.js

4. Асинхронний I/O

libuv уміє працювати із системними викликами:

  • epoll (Linux),
  • kqueue (macOS, BSD),
  • IOCP (Windows),
  • event ports (Solaris).

Ці механізми дозволяють ефективно відстежувати події (наприклад, читання з сокета) без блокування потоку, поки операція не завершиться.

Це основа неблокуючого введення-виведення (non-blocking I/O).

5. Таймери та черги задач

libuv керує:

  • setTimeout і setInterval;
  • setImmediate і process.nextTick;
  • внутрішніми чергами подій (microtasks, macrotasks).

Кожна категорія має свою фазу виконання всередині Event Loop:

javascript
timers → I/O callbacks → idle/prepare → poll → check → close callbacks

6. Взаємодія з V8 та Node.js

libuv не виконує JavaScript - це робить V8. Але вона:

  1. отримує асинхронні задачі від JS (через Node.js bindings);
  2. виконує їх у фоні або чекає системних подій;
  3. повертає результати назад у V8 через Event Loop.

7. Приклад у дії

javascript
const fs = require('fs'); console.log('Початок'); fs.readFile('data.txt', 'utf-8', (err, data) => { console.log('Файл прочитано'); }); setTimeout(() => console.log('Таймер спрацював'), 0); console.log('Кінець');

Порядок виконання:

javascript
Початок ← V8 (синхронно) Кінець ← V8 (синхронно) Таймер спрацював ← libuv (через Event Loop) Файл прочитано ← libuv (через Thread Pool)

8. Резюме: ролі libuv

КомпонентРоль
Event LoopКерує чергами подій і callback-ів
Thread PoolВиконує важкі операції у фоні
Async I/OЗабезпечує неблокуюче введення-виведення
ТаймериКерує часом і розкладом задач
Крос-платформністьПрацює однаково на Windows, Linux, macOS

У зв'язці:

javascript
┌────────────┐ JavaScript (виконується в V8) └─────┬──────┘ │ виклики fs, http, timers ┌────────────┐ │ libuv │ (Event Loop, Thread Pool, async I/O) └─────┬──────┘ ┌────────────┐ ОС (API) (файли, мережа, таймери)

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.