زبان های Multi-Threading یا چند نخی

زبان های Multi-Threading یا چند نخی

Thread کوچک‌ترین واحد اجرایی در سیستم عامل است. Thread‌ واحد اساسی اجرایی یا واحد اساسی در بهره‌برداری از CPU به حساب می‌آید.
Thread موجودیتی در درون یک پردازه (پروسه | Process) است که می‌تواند برای اجرا زمان‌بندی شود. یک برنامه تحت اجرا به عنوان یک Process شناخته می‌شود. هر برنامه ممکن است تعدادی پردازه مرتبط داشته باشد و هر پردازه می‌تواند دارای چند Thread باشد که این Threadها آن پردازه را اجرا می‌کنند.
تمام Threadهای یک پردازه فضای آدرس مجازی و منابع سیستمی آن پردازه را با یکدیگر شریک می‌شوند.
 
کارکرد Thread به چه صورت است؟
Threadها معمولاً‌ به وسیله یک زمان‌بند (Scheduler) مدیریت می‌شوند. یک زمان‌بند بخش استانداردی از یک سیستم عامل است.
برای ایجاد یک Thread ابتدا باید یک Process یا پردازه ایجاد شود. پس از آن، پردازه یک Thread ایجاد می‌کند و سپس این Thread اجرا خواهد شد.
هر پردازه حداقل دارای یک Thread است، اما سقفی برای تعداد Threadهای یک پردازه وجود ندارد و پردازه می‌تواند هر تعداد Thread مورد نیازش را به کار گیرد. برای وظایف تخصصی، هر چه تعداد Thread بیش‌تری وجود داشته باشد، عملکرد و کارایی سیستم بهتر خواهد بود.


Process چیست؟
یک پردازه (پردازش | Process) وهله‌ای (نمونه | Instance) از یک برنامه کامپیوتری به حساب می‌آید که به وسیله یک یا تعداد زیادی از Threadها در حال اجرا است. پردازه شامل کدهای برنامه و رفتار آن است. 
 
 
Context Switching چیست؟
«Context Switching» یا «تغییر زمینه» شامل ذخیره مفاد یا وضعیت یک Process در سیستم عامل است تا بتوان در زمان لازم آن را دوباره بارگذاری کرد و اجرای آن پردازه از همان نقطه توقف از سر گرفته شود. Context Switching ویژگی یک سیستم عامل چندوظیفه‌ای است و امکان استفاده چند پردازه از یک CPU واحد را فراهم می‌کند. 

تفاوت Process و Thread چیست؟
به طور خلاصه، Process یا پردازه مجموعه‌ای از کدها، حافظه، داده و سایر منابع است. اما، Thread توالی از کدها به حساب می‌آید که در داخل محدوده یک پردازه اجرا می‌شود.
تفاوت بارز Process و Thread این است که Threadها (همه از یک پردازه) در یک فضای حافظه اشتراکی اجرا می‌شوند، در حالی که پردازه‌ها در فضاهای حافظه جداگانه عمل می‌کنند. Threadها بیش از اینکه قابلیت CPU‌ محسوب شوند، یک قابلیت محیط‌های عملیاتی (سیستم عامل) به حساب می‌آیند. هر پردازه منابع مورد نیاز برای اجرای یک برنامه را فراهم می‌کند.
 
فهرستی از تفاوت‌های کلیدی Process و Thread ارائه شده است:
Process به معنای یک برنامه در حال اجراست، در حالی که Thread به معنی بخشی (Segment) از یک Process به شمار می‌رود.
یک Process سبک‌وزن نیست، در حالی که Thread کم حجم و سبک‌وزن است.
زمان بیش‌تری برای بستن یک Process نسبت به یک Thread نیاز است.
ایجاد یک Process نیز نسبت به ایجاد یک Thread نیازمند زمان بیش‌تری است.
برای تغییر زمینه (Context Switching) در Process نسبت به Thread نیاز به زمان بیش‌تری وجود دارد.
یک process به میزان زیادی منزوی است، در حالی که Threadها حافظه و منابع دیگری را در داخل یک پردازه با هم به اشتراک می‌گذارند.
 
Thread در سی پی یو چیست ؟
Threadها قطعاتی مجازی از کدها هستند که هسته فیزیکی یک CPU را به چندین هسته مجازی تقسیم می‌کنند. یک هسته CPU می‌تواند تا دو Thread در هر هسته داشته باشد. برای مثال، در صورتی که یک سی‌پی‌یو دو هسته‌ای (Dual Core) باشد، دارای چهار Thread خواهد بود. همچنین، اگر یک CPU هشت هسته‌ای (Octal Core) باشد، دارای شانزده Thread خواهد بود. Thread به وسیله یک پردازه ایجاد می‌شود.
 

نحوه ایجاد و تخصیص Thread در CPU چگونه است؟
Threadها همیشه به وسیله سیستم عامل برای اجرای یک وظیفه در یک برنامه خاص ایجاد می شوند. ابتدا یک Thread وجود دارد که مربوط به کدهای انجام محاسبات یک هسته CPU است و به آن Thread اصلی (Primary Thread) گفته می‌شود. این Thread اطلاعات را از کاربر دریافت می‌کند و سپس Thread دیگری ایجاد می‌کند و کاری که باید انجام شود را به آن Thread‌ جدید اختصاص می‌دهد. به همین شکل، در صورت دریافت یک دستورالعمل دیگر، Thread دیگری ایجاد می‌شود و آن وظیفه به Thread جدید اختصاص داده خواهد شد.


Hyper Threading چیست؟
فناوری Hyper Threading به یک هسته CPU واحد اجازه می‌دهد به عنوان دو هسته عمل کند که منجر به افزایش سرعت اجرای یک برنامه یا اپلیکیشن می‌شود. حتی با یک هسته CPU می‌توان به گونه‌ای شبیه‌سازی انجام داد که گویی دو هسته وجود دارد. هر چه تعداد Threadها بیش‌تر باشد، میزان عملکرد و کارایی سیستم بهتر خواهد بود. در صورتی که CPU دو هسته‌ای باشد، با استفاده از Hyper Threading این دو هسته مانند چهار هسته عمل خواهند کرد.

Multi Thread یا چندنخی چیست؟
استفاده همزمان از چند Thread‌ در یک پردازه، Multithreading یا چندنخی گفته می‌شود. به همین دلیل، Threadها بسیار کاربردی هستند و استفاده از آن‌ها بهره‌وری سیستم را به میزان زیادی افزایش می‌دهد.

 پردازه Multi Thread با Single Thread 
 
 
تفاوت Concurrency و Parallelism چیست ؟
دو اصطلاح Concurrency و Parallelism اغلب در ارتباط با برنامه‌های چندنخی به کار برده می‌شوند. Concurrency به معنای همزمانی و Parallelism به معنی اجرای موازی است.
 
 
Concurrency یا همزمانی چیست؟
Concurrency یا همزمانی یعنی یک برنامه (اپلیکیشن) در حال اجرا شدن با بیش از یک وظیفه (Task) در لحظه است. در صورتی که کامپیوتر تنها دارای یک CPU‌ باشد، ممکن است اپلیکیشن نتواند دقیقاً در یک لحظه خاص بیش از یک وظیفه را پیش ببرد، اما در لحظه بیش از یک وظیفه داخل اپلیکیشن در حال اجرا است. برای اجرای بیش از یک وظیفه به صورت همزمان، CPU‌ در طول اجرا بین وظایف مختلف سوئیچ می‌کند. یعنی در یک لحظه بخشی از یک وظیفه و در لحظه بعد بخشی از وظیفه دیگر را انجام می‌دهد. این مفهوم در تصویر زیر نشان داده شده است:
 
اجرای موازی چیست؟
اجرای موازی (Parallel Execution) وقتی انجام می‌شود که یک کامپیوتر دارای بیش از یک CPU یا هسته CPU‌ باشد و به معنای واقعی بیش از یک وظیفه را در لحظه انجام دهد.
 
 
اجرای همزمان موازی
می‌توان شیوه اجرای موازی همزمان (Parallel Concurrent Execution) را نیز زمانی به کار گرفت که Threadها میان چندین CPU توزیع شده باشند. بنابراین، Threadهای اجرا شده روی یک CPU خاص به صورت همزمان و Threadهای مستقر در CPUهای متفاوت به صورت موازی اجرا خواهند شد. این پدیده در نمودار زیر به تصویر کشیده شده است:
 
مفهوم Parallelism چیست؟
اصطلاح Parallelism به این معنی است که یک اپلیکیشن وظایف خود را به تعدادی زیر وظیفه کوچک‌تر تقسیم می‌کند که می‌توان آن‌ها را به صورت موازی مثلاً‌ در چند CPU دقیقاً در یک لحظه یکسان پردازش کرد. بنابراین، Parallelism به مدل اجرایی «همزمان موازی» که پیش از این معرفی شد ارتباطی ندارد، اگرچه ممکن است این دو اصطلاح در ظاهر مشابه به نظر برسند. برای دستیابی به Parallelism واقعی، اپلیکیشن باید بیش از یک Thread اجرایی در لحظه داشته باشد و هر Thread باید روی یک CPU مجزا، هسته‌های مختلف CPU، هسته‌های کارت گرافیک یا موارد مشابه اجرا شود.
در تصویر زیر یک وظیفه بزرگ‌تر وجود دارد که به چهار زیربخش تقسیم شده است. این چهار زیربخش در حال اجرا به وسیله چهار Thread مختلف روی دو CPU مجزا هستند. این بدین معنا است که بخشی از این زیروظیفه‌ها به صورت همزمان اجرا می‌شوند (آن زیروظیفه‌هایی که در CPUهای یکسان قرار دارند) و تعدادی از آن‌ها که در CPUهای متفاوتی مستقر هستند به صورت موازی اجرا می‌شوند:
 
زبان های Multi-Threading
 
C++
java
python
C#
golang
 
زبان های Single-Thread
 
PHP
Javascript
 
NodeJS با معماری براساس رویداد (event) طراحی شده است، که استفاده از ورودی و یا خروجی به طور asynchronous را فراهم می‌سازد. یک فرآیند (process) بلافاصله، به هنگام فراخوانی رویداد مرتبط اجرا می‌شود و این بدان معنی است که هیچ کدام از فرآیندها، thread را اشغال نمی‌کنند. 
معماری رویداد محوری (event-driven) که فرآیند‌ها را مسدود نمی‌کند (non-blocking)، این اجازه را به شما می‌دهد تا چندین فرآیند را به طور همزمان اجرا کنید، که باعث افزایش سرعت اجرای کد می‌شود.
 
 

پیاده سازی برنامه نویسی موازی در php

سه روش برای پیاده سازی پردازش موازی بیان کردند :

۱- چند فرایندی (Multi Processing ) : به یک نمونه از برنامه ی در حال اجرا فرایند می گویند . این برنامه ی در حال اجرا می تواند نوت پد باشد یا فتوشاب یا php و php این قابلیت را دارد که از خودش به عنوان یک فرایند والد , فرایند فرزند بوجود بیاورد .این فرایند فرزند همزمان با فرایند والد اجرا می شود و یک سری کارها را انجام می دهد.برای استفاده از این روش راه های مختلفی وجود دارد که ۳ مورد از آن را معرفی می کنیم :‌
الف)  استفاده از تابع fork : برای استفاده از این تابع نیاز به یک extension به نام pcntl می باشد .بعد از نصب این extension می توانیم با استفاده از تابع fork فرایند جدیدی را بوجود بیاوریم و این فرایند همانند فرایندهای دیگر که داخل سیستم عامل مشغول کار هستند , کار می کند و تنها تفاوت آن این است که شماره والد دارد تا مشخص شود این فرایند یک فرایند فرزند است و یک والدی دارد .این روش معمولا در محیط command-line استفاده می شود .
چند فرایندی یک سری محدودیت هایی نیز دارد برای مثال در محیط ویندوز کار نمی کند .همچنین وقتی تعداد فرایندهای فرزند زیاد می شود باعث می شود performance و کارایی سرور به شدت پایین بیاید زیرا یا ایجاد هر فرایند فرزند , یک کپی از نرم افزار ایجاد شده که تمام قابلیت نرم افزار را به همراه دارد .(مثال اینکه ۲۰ تا نرم افزار فتوشاپ را همزمان روی سیستم اتون باز کنید)
نکته دیگر اینکه اشتراک منابع بین این فرایندها کنترل نمی شود . فرض کنید دو فرایند برای اجرا به یک فایل مشترک نیاز دارند و حالا یکی از فرایندها اون فایل را در اختیار می گیرد و رها نمی کند یا اصن آن فایل را خذف می کند.این باعث می شود فرایند دوم کاملا دچار مشکل شود.
ب) استفاده از تابع exec : تابع exec  بر اساس یک فرایند مثلا فایل hello.php را اجرا می کند , این فرایند به وجود آمده و بعد از تمام شدن  اجراش نتیجش داخل یک متغیر ریخته می شود تا فرایند والد به آن دسترسی داشته باشد .کارایی این روش نسبت به روش fork کمی بهتر است .
دو روش بالا مشکل مشترکی دارند که فرایند های فرزند نمی توانند با هم ارتباطی برقرار کنند و برای برطرف کردن این مشکل باید از روشی به اسم Piping.روش Piping با استفاده از ورودی خروجی استاندارد ارتباط بین فرایندها را برقرار می کند.مشکل اصلی این روش پیاده سازی پیچیده آن است  .
 
پیشنهاد میشه از چند فرایندی به خاطر مشکلات و پیچیدگی هایی که دارد در پردازش موازی استفاده نشود.
۲- چند نخی (Multi threading) :  نخ به مجموعه ای از دستور العمل ها می گن که داخل یک فرایند ایجاد شده و تحت یک فرایند به صورت همزمان اجرا می شوند. برای استفاده از نخ در php اول باید نسخه ی ZTS پی اج پی (Zend Thread Safety) رو نصب کنیم . این نسخه محدودیت اشتراک منابع را از بین می برد یعنی اگر دوتا نخ بخواهند به یک فایل مشترک دسترسی داشته باشند با استفاده از یک سری مکانیزم های کنترلی این اشتراک منابع مدیریت می شود . سپس  نیاز به extension ای به نام pthreads داریم که آن را باید نصب کنیم.
یکی از مزایایpthreads extension این است که برپایه شی گرایی نوشته شده و استفاده از آن قابل فهم تر می باشد  .
یکی از مشکلات چند نخی این است که اگر چند نخ را را در قالب یه فرایند اجرا کنیم چنانچه یکی از این نخ ها به مشکل بر بخورد باعث می شود کل فرایند دچار خطا شده و متوقف شود .از بین رفتن نخ ها  و فرایندها و تولید دوباره آنها خیلی هزینه بر است . به همین دلیل توصیه می شود وقتی از چند نخی  استفاده می کنید تمام خطاها را مدیریت کنید تا این مشکلات پیش نیاید.
در کل روش چند نخی از روش  فرایندی معقول تر و بهتر است .
 
۳- توزیع فرایندها (Distributed processing) :‌با استفاده از توزیع فرایندها می توانید فرایندها را بین کامپیوتر ها یا سرور های مختلف پخش کنیم و از منابع آنها استفاده کنیم .یکی از راه های توزیع فرایندها , برنامه نویسی سوکت است . راه دیگه استفاده از کتابخانه های php است .این کتابخانه ها باعث می شوند پیچیدگی کم تر شده   . از جمله این کتابخانه ها zeromq و gearman می باشند.این کتابخانه ها بر اساس ساختار داخلی ای که دارن ارسال و دریافت را اتوماتیک مدیریت می کنند و فقط لازم هست برای آنها یک worker قرار دهیم . این worker ها در سرور های مختلف پخش می شوند و وظیفه پردازش فرایندهای مارا دارند  و خویبش این هست این کتابخانه خودشون تصمیمی میگیرند درخواست به کدام سرور برود و …..
نکته ایجاست که می توانید در یک سرور نیز worker های مختلفی ایجاد کنیم و پردازش موازی را اجرا کنیم .
و به نظر  من روش توزیع فرایندها جزو بهترین روش ها برای پیاده سازی پردازش موازی است .
 
نویسنده :
مجید پورداود
  • مجید پورداود
  • مهندس نرم افزار و تحلیلگر ارشد سیستم های کامپیوتری تحت وب می باشم. از سال 1395 برنامه نویسی را شروع کردم و به زبان های php (فریم ورک laravel -codeigniter)  و زبان جاوا اسکریپت (فریم ورک express.js-nest.js)  تسلط دارم.  

ثبت دیدگاه جدید

0 دیدگاه

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *