Skip to content

Parallel programming in Node.js: mutex, semaphore, atomics, worker threads, worker pools

Notifications You must be signed in to change notification settings

Skippia/parallel-programming-playground

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

parallel-programming-playground

Примитивы параллельного и конкурентного программирования в Node.js — от мьютексов и семафоров до распределённых блокировок Redis и worker-пулов.

Оглавление


Sync-примитивы (Mutex)

Кросс-потоковая синхронизация через SharedArrayBuffer + Atomics.

Модуль Описание
Mutex-1 Реализация на Atomics.exchange() + Atomics.wait()
Mutex-2 Реализация на Atomics.compareExchange()
Mutex-3-broken Намеренно сломанная реализация (для демонстрации ошибок)
Async Mutex Обёртка поверх Mutex с async/await интерфейсом

Дополнительно:

  • Deadlock — два потока захватывают блокировки в разном порядке
  • Livelock (2 варианта) — потоки постоянно уступают друг другу без прогресса
  • Point race condition — демонстрация гонки на структуре данных (x, y) и её устранение через Mutex
src/sync-primitives/mutex/

Sync-примитивы (Semaphore)

Бинарные и счётные семафоры на Atomics.

Модуль Описание
Race condition demo 22 воркера делятся на 2 группы — гонка без защиты
Binary semaphore (naive) Наивная реализация на флаге — небезопасна
Binary semaphore (atomics) Корректная реализация через Atomics.compareExchange()
Binary semaphore (atomics v2) Альтернативная атомарная реализация
Counting semaphore Общий счётный семафор — допускает N одновременных участников
src/sync-primitives/semaphore/

Async-примитивы

Координация конкурентных async-операций внутри одного потока (event loop), без SharedArrayBuffer.

Примитив Описание
AsyncMutex Взаимное исключение через FIFO-очередь промисов. Защита in-memory состояния, соединений к БД
AsyncSemaphore Ограничение конкурентности до N задач (аналог p-limit). Демо: 10 URL с макс. 3 параллельными запросами
Barrier Точка синхронизации: все N участников должны дойти до барьера, прежде чем любой продолжит. Поддержка повторного использования через генерации. Демо: кросс-поточный барьер через SharedArrayBuffer
BoundedChannel Async MPSC-канал с backpressure (вдохновлён Go/Rust). send() блокирует при заполнении, receive() — при пустом буфере
AsyncRWLock Множество читателей ИЛИ один писатель. Write-preferring (предотвращает голодание писателей)
Token Bucket Классический алгоритм rate limiting — допускает кратковременные всплески до capacity (AWS API Gateway, nginx)
Sliding Window Строгий rate limiter — ровно N запросов в окне, без всплесков (GitHub API)
src/async-primitives/

Бенчмарки Atomics

Сравнение стратегий атомарных операций на 15 потоках × 100M инкрементов.

Файл Стратегия
1-atomics.ts Базовый Atomics.add() на общем буфере
2-sharding.ts Шардирование — каждый поток в свой SharedArrayBuffer
3-int.ts Обычные Int32Array-операции
4-non-atomic-sharding.ts Шардирование без атомарности (демонстрация проблем)
5-workerpool-atomic.ts Atomics.add() через npm workerpool
6-workerpool-int.ts Int-операции через workerpool
src/atomic-benchmarks/

Lock-free

CAS-счётчик (Compare-And-Swap) — основа lock-free структур данных.

Алгоритм: Atomics.load() → вычисление нового значения → Atomics.compareExchange() → retry при contention.

Бенчмарк: CAS loop vs Atomics.add() vs Mutex.

src/lock-free/cas-counter.ts

Распределённые блокировки

Распределённый мьютекс на Redis (SET NX EX).

  • Атомарный захват блокировки с TTL
  • Атомарное освобождение через Lua-скрипт (проверка владельца)
  • Watchdog auto-renewal — автопродление TTL при долгих операциях
  • Экспоненциальный backoff + jitter при retry
  • Защита от deadlock: авто-истечение при падении процесса

Применение: cron-задачи, миграции, leader election между инстансами.

Для запуска демо нужен Redis:

docker run -d -p 6379:6379 redis
src/distributed/redis-lock/

Worker Threads

Базовые паттерны работы с worker_threads.

Модуль Описание
Single-file worker Один файл как main и worker (isMainThread), передача workerData, postMessage()
Image resize Ресайз изображений через sharp в воркерах (1920×, 1280×, 640×)
Express + bcrypt server Express-сервер с CPU-интенсивным bcrypt.hash(). Два варианта: 1 воркер и 4 воркера
src/worker-thread/

Worker Pools

Пулы воркеров с очередями задач.

Модуль Описание
Кастомная реализация Собственный WorkerPool с idle-map, очередью задач, цепочкой then2()
Bcrypt-бенчмарки Express-сервер: без пула ~60 req/sec, с workerpool ~8700 req/sec
Video resize Ресайз видео через fluent-ffmpeg + StaticPool из node-worker-threads-pool
workerpool vs worker-threads Сравнение npm workerpool и нативных worker_threads — бенчмарки производительности
src/worker-pool/

Стек технологий

  • Node.js worker_threads, Atomics, SharedArrayBuffer
  • ioredis — Redis-клиент для распределённых блокировок
  • express + helmet + morgan — HTTP-сервер
  • bcrypt — CPU-интенсивное хэширование паролей
  • sharp — обработка изображений
  • fluent-ffmpeg — обработка видео
  • workerpool, node-worker-threads-pool — пулы воркеров

Установка и запуск

npm install

# Запуск любого модуля
npx tsx src/<путь-к-файлу>.ts

# Примеры
npx tsx src/sync-primitives/mutex/1-mutex-base.ts
npx tsx src/async-primitives/async-semaphore/demo-concurrent-requests.ts
npx tsx src/distributed/redis-lock/demo.ts
npx tsx src/worker-pool/2-bcrypt-experiments/server.ts

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •