Parent PID 1001 Child PID 2042 DETACHED

Detached Spawn
Test

Как запускать независимые дочерние процессы и тестировать их — полный гайд по Node.js и Electron

Что такое Detached Spawn?

const child = spawn ( 'npm' , { detached: true , stdio: 'ignore' } ); child. unref ();

Detached spawn — это запуск дочернего процесса, который полностью независим от родительского. Даже если родитель завершится — дочерний процесс продолжит работать.

В Node.js это достигается через опцию detached: true в сочетании с stdio: 'ignore' и вызовом child.unref().

На Unix дочерний процесс становится лидером новой группы процессов. На Windows — создаётся новое консольное окно.

Ключевые факты в цифрах

<50ms
Время запуска дочернего процесса
🔗
0
Зависимость от родителя после detach
🖥️
2
Платформы: Unix process group / Windows console
📊
Количество одновременно запущенных detached процессов
🛡️
1
Правило: stdio должен быть 'ignore' для background-режима

Базовый паттерн

// Запуск независимого процесса const { spawn } = require('child_process'); const child = spawn('node', ['server.js'], { detached: true, stdio: 'ignore' // ОБЯЗАТЕЛЬНО для фона! }); child.unref(); // Отвязка от event loop // Родитель может завершиться — // дочерний процесс продолжит работать

Три ключевых элемента: detached: true создаёт новую группу процессов, stdio: 'ignore' разрывает каналы ввода-вывода, unref() позволяет родителю завершиться.

Сравнение подходов

Detached Spawn (полная изоляция)95%
fork() (общий event loop)60%
exec() (буферизованный вывод)45%
spawn() без detached (привязан)35%
Worker Threads (в одном процессе)55%

Типичные сценарии

Фоновые задачи

85% — cron, очереди, обработчики

Серверы

65% — игровые, API, dev-серверы

Electron App

40% — helper-процессы из renderer

Демоны

55% — логгеры, мониторинг, агенты

Жизненный цикл Detached Spawn

1

Родитель

Вызывает spawn с detached: true

2

Process Group

OS создаёт новую группу

3

stdio: ignore

Разрыв каналов ввода-вывода

6

Демон

Работает как daemon-процесс

5

unref()

Отвязка от event loop

4

Родитель exit

Завершается без влияния на child

Мифы и реальность

Миф: detached = fork

fork() запускает процесс в общем event loop и не создаёт независимый процесс.

Реальность: новая группа процессов

detached создаёт отдельный process group, полностью независимый от родителя.

Миф: stdio не важен

Без stdio: 'ignore' процесс НЕ уйдёт в фон — он останется привязан к родителю.

Реальность: stdio = 'ignore' обязательно

Только с 'ignore' дочерний процесс становится полностью автономным daemon'ом.

Миф: unref() обязателен

unref() нужен только чтобы родитель мог завершиться. Без него — родитель ждёт.

Реальность: unref() для удобства

unref() позволяет event loop'у родителя завершиться, не дожидаясь child.

Цифры и факты

setpgid()
Unix: дочерний процесс становится лидером новой группы через setpgid(0, 0)
true
detached флаг
'ignore'
stdio режим
CREATE_NEW_PROCESS_GROUP
Windows: вместо setpgid используется CREATE_NEW_PROCESS_GROUP через flags. На Windows поведение отличается — создаётся новая консоль.
child.unref()
Удаёт child из event loop родителя — позволяет родителю завершиться, не дожидаясь завершения дочернего процесса. Без unref() родитель будет ждать.

История и эволюция

2009 — Node.js v0.1

child_process появляется в первых версиях Node.js. spawn() уже поддерживает создание дочерних процессов.

2011 — detached: true

Добавлена опция detached для создания независимых процессов. Unix использует setpgid, Windows — CREATE_NEW_PROCESS_GROUP.

2013 — Electron (Atom Shell)

Electron использует detached spawn для запуска helper-процессов из renderer. Проблема: Windows Security может silently убивать процессы.

2016 — Node.js issue #5614

Обнаружено: spawn-ed detached unref-ed child process в Windows всё ещё предотвращает exit родителя без stdio: 'ignore'.

2020+ — Современный паттерн

Стандартный паттерн: { detached: true, stdio: 'ignore' } + child.unref(). Используется в Electron, VS Code, OpenClaw и других.

Преимущества Detached Spawn

🔓

Полная независимость

Дочерний процесс не завершается при выходе родителя — работает автономно.

⚙️

Фоновые демоны

Идеально для демонов, логгеров, мониторинга — запускай и забывай.

🖥️

Кроссплатформенность

Работает на Unix (process group) и Windows (новая консоль) с разным поведением.

🔌

Electron-ready

Запускай helper-процессы из renderer — они переживут закрытие основного окна.

📈

Масштабируемость

Каждый detached процесс — отдельный OS process. Используй все ядра CPU.

🛡️

Изоляция ошибок

Краш дочернего процесса не влияет на родительский — полная изоляция.

Ключевые правила

// ✅ Правильный паттерн const child = spawn(cmd, args, { detached: true, stdio: 'ignore' }); child.unref(); // ❌ Без stdio: 'ignore' — процесс не уйдёт в фон // ❌ Без unref() — родитель будет ждать child // ❌ Без detached — child умрёт с родителем
«Detached spawn — это как запустить спутник на орбиту. Ракета-носитель завершает миссию, а спутник работает автономно.»
Parent ✕ Detached ✓