Коротка відповідь
juniorfork() — це wrapper над POSIX fork, який створює дочірній процес із копією пам’яті; spawn() — це wrapper над exec, який створює новий процес і запускає в ньому задану команду. fork() підходить, коли потрібно продовжити виконання у дочірньому процесі того ж коду; spawn() використовується, коли треба запустити зовнішню програму. У Node.js fork() створює child process з IPC каналом, а spawn() – просто процес без IPC.
Повне пояснення
Що це і навіщо
- fork() – системний виклик POSIX, який дублікує поточний процес. У Node.js wrapper
child_process.fork()створює дочірній процес, що запускає інший JavaScript‑файл і встановлює двосторонню IPC‑канал. - spawn() – виклик
child_process.spawn()створює новий процес і запускає в ньому задану команду (наприклад,ls,python). IPC не створюється за замовчуванням.
Ключові принципи/терміни
- Process isolation – fork копіює пам’ять, spawn запускає зовнішню програму.
- IPC – fork має
process.send()/on('message'), spawn може використовувати stdout/stderr. - Memory usage – fork споживає більше пам’яті через копіювання.
Як це працює
- При виклику
fork()ядро створює новий процес, копіюючи адресний простір. Дочірній процес отримує власну копію змінних, але спільний код. - При
spawn()ядро запускає новий процес з вказаною командою, передає аргументи та середовище.
Практика і реалізація (Node.js)
// fork example
const { fork } = require('child_process');
const child = fork('./worker.js');
child.on('message', msg => console.log(msg));
// spawn example
const { spawn } = require('child_process');
const ls = spawn('ls', ['-lh', '/usr']);
lst.stdout.on('data', data => console.log(data.toString()));
Тестування
- Для fork: перевірити IPC‑повідомлення, використовуючи Jest.
- Для spawn: мокати stdout/stderr за допомогою
child_process.spawnSyncу тестах.
Безпека
- fork() може бути ризикованим, якщо дочірній процес виконує небезпечний код; слід обмежувати доступ до ресурсів.
- spawn() дозволяє запускати сторонні програми, тому важливо валідувати вхідні аргументи.
Особливості у контексті Node.js
- fork() створює процес, що запускає інший JS‑файл; це корисно для worker‑threads.
- spawn() використовується для запуску командного рядка, наприклад,
npm,docker.
Оптимізація та типові помилки
- fork() збільшує використання пам’яті; у великих програмах краще використовувати
worker_threads. - spawn() може завершитися з помилкою, якщо команда не знайдена; перевіряйте
error‑подію.
Диагностика
- Якщо дочірній процес не отримує IPC‑повідомлення, перевірте
child.send(). - Якщо spawn не запускає команду, переконайтеся, що шлях до виконуваного файлу правильний.
Альтернативи
worker_threadsдля одночасного виконання коду без копіювання пам’яті.child_process.execдля запуску команд з повним буфером виводу.
Часті помилки (8)
- Неочікуване завершення fork‑процесу через
process.exit(). - IPC‑потік розірваний, бо дочірній процес закрився.
- spawn‑команда не знайдена у PATH.
- Перевищення лимиту процесів (ulimit).
- Неправильне використання
stdioу spawn. - Залишені zombie‑процеси після fork.
- Неправильна обробка
stderrу spawn. - Використання fork для запуску великого JS‑файлу, що збільшує пам’ять.
Cheatsheet
fork(modulePath, args?, options?)– IPC‑канал.spawn(command, args?, options?)– stdout/stderr streams.exec(command, options?, callback)– буферизований вивід.