راهنمای جامع Worker Threads در Node.js (ماژول node:worker_threads)

ماژول node:worker_threads امکان اجرای واقعی چندریسمانی (Multithreading) را در Node.js فراهم می‌کند. برخلاف مدل تک‌ریسمانی سنتی Node.js، Worker Threads اجازه می‌دهند کارهای سنگین CPU در ریسه‌های جداگانه اجرا شوند بدون اینکه حلقهٔ رویداد (Event Loop) مسدود شود. این ماژول از حافظهٔ اشتراکی، انتقال بدون کپی (Zero‑Copy)، کانال‌های پیام، Worker Pool، محدودیت منابع و ابزارهای همگام‌سازی پیشرفته پشتیبانی می‌کند. Worker Threads برای پردازش‌های محاسباتی سنگین ایده‌آل هستند، در حالی که I/O همچنان باید توسط ریسهٔ اصلی مدیریت شود.

Worker ThreadsisMainThreadworkerDataparentPortMessageChannelSharedArrayBuffer

~3 دقیقه مطالعه · آخرین به‌روزرسانی ۹ دی ۱۴۰۴

1. معرفی


ماژول node:worker_threads امکان اجرای جاوااسکریپت در ریسه‌های جداگانه را فراهم می‌کند. هر Worker محیط مستقل خود را دارد اما می‌تواند با ریسهٔ اصلی ارتباط سریع و کارآمد برقرار کند. این قابلیت برای کارهای CPU-محور بسیار مناسب است.


2. نحوهٔ دسترسی


const {
  Worker,
  isMainThread,
  parentPort,
  workerData,
  threadId
} = require('node:worker_threads');

3. چرا از Worker Threads استفاده کنیم؟


  • اجرای موازی کارهای سنگین CPU مانند پردازش تصویر، رمزنگاری، فشرده‌سازی.
  • حافظهٔ اشتراکی با SharedArrayBuffer برای تبادل سریع داده.
  • هزینهٔ کمتر نسبت به child_process یا cluster.
  • انتقال بدون کپی برای ArrayBuffer و MessagePort.

4. مثال پایه


محاسبهٔ سنگین Fibonacci در یک Worker:

// main.js
const { Worker, isMainThread } = require('node:worker_threads');

if (isMainThread) {
  const worker = new Worker(__filename, { workerData: { num: 40 } });

  worker.on('message', (result) => {
    console.log('Fibonacci result:', result);
  });

  worker.on('exit', (code) => {
    console.log('Worker exited with code', code);
  });
} else {
  const { workerData, parentPort } = require('node:worker_threads');

  function fib(n) {
    return n <= 1 ? n : fib(n - 1) + fib(n - 2);
  }

  parentPort.postMessage(fib(workerData.num));
}

5. مفاهیم اصلی


5.1 isMainThread


در ریسهٔ اصلی true و داخل Worker مقدار false دارد.


5.2 workerData


داده‌ای که هنگام ساخت Worker ارسال می‌شود.


5.3 parentPort


کانال پیام Worker → Parent.


5.4 threadId


شناسهٔ یکتا برای هر Worker.


6. پیام‌رسانی و Transfer List


6.1 انتقال بدون کپی


const buffer = new ArrayBuffer(1024);
parentPort.postMessage(buffer, [buffer]); // buffer از دسترس خارج می‌شود

6.2 SharedArrayBuffer


حافظهٔ واقعاً مشترک بین ریسه‌ها:

const shared = new SharedArrayBuffer(4);
const view = new Int32Array(shared);
Atomics.store(view, 0, 42);

7. MessageChannel


ایجاد کانال پیام اختصاصی:

const { MessageChannel } = require('node:worker_threads');
const { port1, port2 } = new MessageChannel();
worker.postMessage({ port: port2 }, [port2]);

8. قابلیت‌های پیشرفته


8.1 Worker Pool


استفادهٔ مجدد از Workerها برای کاهش هزینهٔ ساخت.


8.2 SHARE_ENV


new Worker(__filename, { env: worker_threads.SHARE_ENV });

8.3 محدودیت منابع


new Worker(__filename, {
  resourceLimits: {
    maxOldGenerationSizeMb: 200,
    stackSizeMb: 4
  }
});

8.4 BroadcastChannel


const bc = new BroadcastChannel('updates');
bc.postMessage('Hello workers!');

8.5 Locks API (آزمایشی)


await locks.request('critical', async () => {
  // فقط یک Worker در لحظه وارد می‌شود
});

8.6 پروفایل CPU و Heap Snapshot


await worker.startCpuProfile();
await worker.getHeapSnapshot();

8.7 خاتمهٔ Worker


await worker.terminate();

9. بهترین شیوه‌ها


  • فقط برای کارهای CPU-محور استفاده شود.
  • برای داده‌های بزرگ از Transfer List استفاده کنید.
  • SharedArrayBuffer را با احتیاط و آگاهی از Race Condition به‌کار ببرید.
  • برای کارهای تکراری از Worker Pool استفاده کنید.
  • از مسدود کردن ریسهٔ اصلی پرهیز کنید.

10. مواردی که نباید از Worker Threads استفاده کرد


  • کارهای سادهٔ I/O.
  • وظایف بسیار کوتاه (هزینهٔ Worker بیشتر از سود آن است).
  • کارهایی که قابل موازی‌سازی نیستند.

نتیجه‌گیری


ماژول node:worker_threads امکان اجرای موازی واقعی را در Node.js فراهم می‌کند. با پشتیبانی از حافظهٔ اشتراکی، انتقال بدون کپی، Worker Pool و ابزارهای همگام‌سازی، این ماژول برای پردازش‌های سنگین مانند رمزنگاری، پردازش تصویر، فشرده‌سازی و محاسبات علمی کاملاً مناسب است. استفادهٔ صحیح از Worker Threads می‌تواند کارایی برنامه را به‌طور چشمگیری افزایش دهد بدون اینکه حلقهٔ رویداد مسدود شود.


نوشته و پژوهش‌شده توسط دکتر شاهین صیامی

مقالات مرتبط

آشنایی کامل با ماژول Cluster در Node.js و نحوه افزایش مقیاس‌پذیری سرور

ماژول Cluster در Node.js به توسعه‌دهندگان اجازه می‌دهد چندین پردازش همزمان ایجاد کنند که یک پورت سرور را به اشتراک می‌گذارند. این کار باعث استفاده بهتر از هسته‌های CPU و افزایش توان پردازش برنامه می‌شود. در این مقاله نحوه کار Cluster، مدیریت Workerها، تنظیمات مهم و مثال عملی را بررسی می‌کنیم.

ادامه

راهنمای جامع ماژول VM در Node.js (ماژول node:vm)

ماژول node:vm امکان کامپایل و اجرای کد جاوااسکریپت در کانتکست‌های ایزولهٔ V8 را فراهم می‌کند. این کانتکست‌ها مانند یک «سندباکس سبک» داخل برنامهٔ Node.js عمل می‌کنند و هرکدام globalThis مخصوص خود را دارند. این ماژول برای اجرای پویا، موتورهای قالب (Template Engines)، سیستم‌های افزونه (Plugin Systems)، REPLها و تست ایزولهٔ منطق بسیار مناسب است. اما نکتهٔ بسیار مهم: vm یک ابزار امنیتی نیست و نباید برای اجرای کدهای غیرقابل‌اعتماد استفاده شود.

ادامه

راهنمای جامع ماژول V8 در Node.js (ماژول node:v8)

راهنمای جامع ماژول V8 در Node.js (ماژول node:v8)

ادامه

راهنمای جامع ماژول util در Node.js

ماژول node:util مجموعه‌ای از توابع کمکی قدرتمند برای استفاده در هستهٔ Node.js و همچنین توسعهٔ برنامه‌ها ارائه می‌دهد. این ماژول ابزارهایی برای دیباگ، بازرسی اشیا، تبدیل Callback ↔ Promise، قالب‌بندی رشته‌ها، بررسی انواع، مدیریت خطاها، رمزگذاری متن، پردازش MIME، پارس آرگومان‌های CLI، سیگنال‌های Abort، و ابزارهای متفرقه فراهم می‌کند. این ماژول یکی از جعبه‌ابزارهای اصلی و ضروری برای توسعه‌دهندگان Node.js است.

ادامه

راهنمای جامع ماژول URL در Node.js

ماژول node:url ابزارهایی برای تحلیل، ساخت، و دست‌کاری URLها در Node.js فراهم می‌کند. Node.js دو API برای کار با URL دارد: WHATWG URL API — استاندارد مدرن و سازگار با مرورگرها (توصیه‌شده). Legacy API — API قدیمی Node.js (غیرتوصیه‌شده). WHATWG URL API یک رابط تمیز، سازگار و قدرتمند برای کار با اجزای URL، پارامترهای query، الگوهای URL و حتی Blob URLها ارائه می‌دهد.

ادامه

Comprehensive Guide to UDP/Datagram Sockets in Node.js

The node:dgram module provides a full implementation of UDP (User Datagram Protocol) sockets in Node.js. . UDP is a lightweight, connectionless protocol ideal for real‑time applications such as VoIP, gaming, telemetry, IoT, and multicast/broadcast systems. This module exposes APIs for creating sockets, sending and receiving datagrams, joining multicast groups, managing buffer sizes, and controlling low‑level socket behavior.

ادامه