نخ های جداگانه در نود جی اس

Separate threads in Node.js

اگر تجربه‌ی کاری با Node.js داشته باشید، احتمالاً با مزایا و محدودیت‌های مدل تک نخی (single-threaded) آشنا هستید. Node در بطن خود از event loop استفاده می‌کند تا بتواند هزاران درخواست هم ‌زمان را بدون نیاز به thread های زیاد مدیریت کند. اما وقتی پای وظایف محاسباتی سنگین یا طولانی وسط میاد، همین مزیت به نقطه‌ضعف تبدیل می‌شه.

ناجی ما worker_threads  وارد میشود

در گذشته، برای انجام وظایف سنگین محاسباتی در Node.js، معمولاً به سراغ راه‌حل‌هایی مثل child process یا حتی انتقال بار محاسباتی به سرویس‌های دیگر می‌رفتیم. اما این روش‌ها همیشه سریع یا بهینه نبودند. با معرفی worker_threads از نسخه 10.5 به بعد، حالا میشه در خود Node.js و بدون نیاز به سیستم‌های خارجی، thread های جداگانه ایجاد کرد.

تفاوت worker_threads با child_process
قبل از اینکه عمیق‌تر شویم، باید تفاوت اصلی بین این دو را بدانیم:

child_process یک پردازش جداگانه ایجاد می‌کند؛ هیچ حافظه‌ای را با فرآیند اصلی به اشتراک نمی‌گذارد.

worker_threads یک thread در همان پردازش ایجاد می‌کند که می‌تواند حافظه را با main thread به اشتراک بگذارد از طریق SharedArrayBuffer در نتیجه سرعت بیشتر و هزینه کمتری داریم.

بطور مثال( اپلود در FTP یا فشرده کردن فایل) از کار هایی هست که میتونیم به worker_threads بسپاریم.

استفاده از SharedArrayBuffer برای به اشتراک‌گذاری داده
در مواقعی که لازم است داده‌ای بین چند worker و thread اصلی به اشتراک گذاشته شود (مثل پردازش تصویر، هوش مصنوعی، یا stream‌های سنگین)، SharedArrayBuffer و Atomics بهترین ابزارها هستند.

مثلاً میتونیم آرایه‌ای از اعداد را در shared buffer ذخیره کرده و چند worker روی آن پردازش انجام دهند بدون اینکه نیازی به serialization یا cloning باشد.

نکات مهم در استفاده از Worker Threads
ساخت تعداد زیاد worker (مثل ۱۰۰۰ عدد) اصلاً ایده خوبی نیست؛ چون threadها منابع سیستم را مصرف می‌کنند.

حتماً از pool استفاده کنید، مثلاً با کتابخانه‌هایی مانند poolifier یا با پیاده‌سازی دستی.

در پردازش‌های موازی باید همیشه race condition ها و sync را مدیریت کنید.  استفاده از Atomics کمک بزرگی می‌کند.

از پیام‌ها فقط برای کنترل یا ارسال داده‌ی سبک استفاده کنید. اگر داده‌ی سنگینی دارید، از SharedArrayBuffer استفاده کنید.

جمع‌بندی
اگر با Node.js کار می‌کنید و با bottleneck های محاسباتی یا lag در event loop مواجه شده‌اید، وقتش  رسیده که worker_threads رو جدی بگیرید. این ابزار قدرتمند، شما را یک قدم به توسعه اپلیکیشن‌های real-time و مقیاس‌پذیر نزدیک‌تر می‌کند. درست استفاده کردن از آن، یعنی مدیریت بهتر منابع، کارایی بیشتر، و کاربران راضی‌تر.