اگر تا به حال اسم Node.js به گوشتون خورده باشه ، به احتمال زیاد با اصطلاحاتی مثل Multi-threading و Multi-Processing هم آشنایی دارید. در این مقاله ما به مبحث Multi-threading میپردازیم و شما رو دعوت میکنم که حتما این مقاله بسیار مفید رو هم مطالعه کنید تا با فرق های thread و process آشنا بشید.
تاریخچهی JavaScript به عنوان یک زبان single-thread :
ابتدا JavaScript به دلیل سادگی و آسانی به صورت یک زبان تک thread طراحی شد. طبیعت تک ترد JavaScript به محیطی که برای اجرا در اون طراحی شده بود، یعنی مرورگر وب، وابسته هست.
مدل حلقه رویداد ( Event-Loop ) این اجازه رو میده که JavaScript رویدادها را به صورت متوالی، یکی پس از دیگری، به صورت غیر مسدود کننده پردازش کنه. این معماری مبتنی بر رویداد، باطراحی asynchronous و ماهیت تعاملی برنامههای وب بسیار سازگاره.
JavaScript با DOM در مرورگرهای وب تعامل بسیار زیادی داره. DOM نمایش درختی از صفحه وب است و دستکاری مستقیم DOM از چندین ترد میتونه منجر به مسائل synchronization و consistency بشه. با نگهداشتن JavaScript به صورت تک ترد ، دسترسی به DOM قابل کنترل و سادهتر میشود.
چرا استفاده از معماری multi-thread مهم است؟
معماری multi-thread بهویژه برای عملیاتهای پر هزینه مناسبه . با تقسیم بار کاری به چندین ترد، میتونیم از منابع موجود پردازنده بهرهوری مناسبی کنیم و نسبت به اجرای مسائل به صورت متوالی، عملکرد بهتری داشته باشیم.
همینطور بهطور معمول در برنامههای سمت سرور برای پردازش چندین اتصال کاربر بهصورت همزمان استفاده میشه. هر اتصال کاربر میتونه در یک thread جداگانه پردازش شود، که امکان پردازش همزمان درخواستها و بهبود قابلیت مقیاسپذیری را فراهم میکند.
مشکلات multi-threading :
مهمه بهیاد داشته باشیم که هرچند multi-threading مزایای بسیاری ارائه میده،اما چالشهایی هم با اون همراه هست، مثل همگامسازی، بهاشتراکگذاری دادهها و شرایط رقابتی احتمالی (race conditions). طراحی دقیق و مدیریت کد چند ترد نیازمند اطمینان از ایمنی thread و جلوگیری از مشکلات مرتبط با concurrency هست.
thread های کارگر : جایگزینی برای multi-threading
تردهای کارگر (Worker Threads) به JavaScript و Node.js معرفی شدند تا محدودیت اجرای single thread را حل کنن ، جایی که همهی عملیات توسط یک ترد انجام میشود. این طبیعت تک تردی میتواند به شرایط مسدود کنندگی منجر بشه ، که عملیاتهای طولانی یا پرهزینه پردازنده میتونه به طور قابل توجهی بر کارآیی برنامه یا ایجاد تاخیر در مدیریت درخواستها یا تعاملات کاربری تأثیر بگذاره.
تردهای کارگر به ویژه برای وظایفی مانند محاسبات سنگین، پردازش دادههای فشرده یا انجام عملیاتی که شامل ارتباطات شبکه مناسب هستن. با اجرای این وظایف در تردهای جداگانه، میتونیم ترد اصلی را آزاد نگه داریم تا به هندل کردن تعاملات کاربری بپردازه و پاسخگویی برنامه را تضمین کنه.
یک پیادهسازی بسیار ساده:
- ایجاد تردهای کارگر: ما میتونیم با نمونهسازی شیء Worker و ارسال URL یک فایل JavaScript که در ترد کارگر اجرا میشه، یک ترد کارگر جدید ایجاد کنیم.
- در ترد اصلی، میتونیم با استفاده از متد ()worker.postMessage پیامهایی رو به ترد کارگر ارسال کنیم.
- دریافت نتایج : در ترد اصلی، میتونیم با استفاده از رویداد onmessage پیامهایی رو از ترد کارگر گوش بدیم.
- پایان دادن به تردهای کارگر : وقتی کارمون با ترد کارگر تموم شد ، باید اون رو خاتمه بدیم تا منابع سیستم رو آزاد کنیم. توی ترد اصلی، میتونیم با فراخوانی متد ()worker.terminate ترد کارگر را متوقف کنیم.
// index.js
const { Worker } = require('worker_threads');
const worker = new Worker('worker.js');
worker.postMessage('some data');
// Main thread
worker.onmessage = function(event) {
// Handle the result received from the worker thread
const result = event.data;
// Do something with the result
};
worker.terminate();
در فایل Worker.js داریم :
// Worker thread (worker.js)
self.onmessage = function(event) {
// Handle incoming message from the main thread
const data = event.data;
// Perform some processing
const result = processData(data);
// Send the result back to the main thread
self.postMessage(result);
};
محدودیتهای تردهای کارگر:
در نظر داشته باشید که تردهای کارگر برخی محدودیتهایی دارن. اونها دارای محیط ایزولهای هستن، به این معنی که به DOM، window یا بعضی از واسطهای وب دسترسی ندارن. همچنین ارتباط بین ترد اصلی و تردهای کارگر از طریق ارسال پیام انجام میشه، بنابراین قبل از ارسال اطلاعات باید آنها را سریالیز کنیم و در سمت مقابل آنها را دسریالیز کنیم.
تردهای کارگر در Node.js بهطور مشابه با تردهای کارگر وب در مرورگر عمل میکنن و راهی برای اجرای کد به صورت همزمان و انجام وظایف پسزمینهای فراهم میکنن. با این حال، مهم است بهیاد داشته باشیم که تردهای کارگر Node.js ترد های واقعی سیستمعامل نیستند، بلکه تجسمهای سبکی هستند که بر روی حلقه رویداد ساخته شدن.
نتیجهگیری:
به طور کلی ، تردهای کارگر برای پشتیبانی از محدودیتهای اجرای تک نخی JavaScript و امکان همزمانی در برنامههای JavaScript معرفی شدن.
با استفاده از تردهای کارگر در Node.js، شما میتونید از چندین هسته پردازنده برای وظایف محاسباتی پرهزینه استفاده کنید و عملکرد و پاسخگویی برنامههای Node.js خودتون رو بهبود ببخشید.
امیدوارم این مقاله برای شما مفید بوده باشد
با تشکر فراوان!!!