در بخش قبل با نحوه عملکرد سیستمعامل آشنا شدیم و متوجه شدیم که سیستمعامل چطور Process ها و Thread ها را مدیریت میکند.
مقدمه
از نظر زمان و ترتیب اجرای تسکها، برنامهنویسی را میتوان به دو پارادایم تقسیم کرد.
- Sequential Programming – برنامهنویسی خطی یا متوالی
- Concurrent Programming – برنامهنویسی موازی یا همزمان

تکه کد زیر در پارادایم Sequential Programming نوشته شده است.
import time
def say_hi(name):
time.sleep(1)
print('hi', name)
say_hi('mmreza')
say_hi('Fatima')
say_hi('Mahboobeh')و تکه کد زیر در پارادایم Concurrent Programming نوشته شده است.
import time
import threading
def say_hi(name):
time.sleep(1)
print('hi', name)
threading.Thread(target=say_hi, args=('mmreza', )).start()
threading.Thread(target=say_hi, args=('Fatima', )).start()
threading.Thread(target=say_hi, args=('Mahboobeh', )).start()فعلا از تشريح کدها صرف نظر میکنيم زیرا بعدا به تفصیل به شرح آن خواهیم پرداخت اما پیشنهاد میکنم هر دو را اجرا کنید تا متوجه تفاوت زمان اجرای آنها شوید.
پارادایم Sequential Programming
Sequential Programming، همان چیزی است که در ابتدای یادگیری برنامهنویسی به یک زبانآموز یاد میدهند. به عبارت دیگر اگر تا امروز با مفهوم برنامهنویسی concurrent آشنا نشدهاید، همه برنامههایی که تا کنون (به خصوص در پایتون) نوشتهاید به سبک sequential نوشته شده است.
در این نوع از برنامهنویسی، پس از اجرای برنامه، سیستمعامل تسکها را به ترتیب یکی پس از دیگری در یک thread قرار میدهد و به ترتیب آنها را اجرا میکند. به عبارت دیگر، همه برنامههایی که در این پارادایم نوشته میشوند، Single-Thread هستند.
در این نوع برنامهنویسی، اجرای هر تسک در گروی این است که تسک قبلی با موفقیت اجرا شده و به پایان برسد. به عبارت دیگر اگر انجام یکی از تسکها بسیار زمان بر باشد، تسکهای بعدی باید آنقدر منتظر بمانند تا این تسک با موفقیت تمام شود. همچنین اگر اجرای یکی از تسکها با خطا مواجه شود، تسکهای بعدی اجرا نخواهد شد.
مثال – کابوس گیر افتادن پشت کامیون
تصور کنید ۲۰ خودروی سواری پشت یک کامیون در یک جاده باریک تکبانده و سربالایی گیر افتادهاند. تنها دو حالت وجود دارد که خودروها نجات پیدا کنند. یا جاده باید کمی پهنتر شود تا راننده بتواند راه را برای سایرین باز کند و یا همه باید آنقدر صبر کنند تا کامیون به مقصد برسد.
- کامیون اشاره به یک تسک با هزینه بالا را دارد.
- خودروهای سواری اشاره به تسکهای سبکتر دارد.
- جاده اشاره به مفهوم process در سیستمعامل دارد.
- هر باند از جاده اشاره به مفهوم thread در سیستمعامل دارد.
- پهنتر شدن جاده مانند این است که منابع سختافزاری را افزایش دهیم.
- متوقف کردن کامیون برای راه دادن به سایر خودروها مانند این است که سیستمعامل اجرای یک تسک را برای لحظاتی متوقف کند تا سایر تسکها نیز بتوانند از منابع سیستم استفاده کنند.
در این مثال سیستمعامل تنها زمانی تسک سنگین را برای لحظاتی متوقف میکند که:
- یا آن تسک برای یک برنامه دیگر باشد. (خود سیستمعامل مدیریت اجرای آن را به عهده داشته باشد)
- یا برنامه را به روش concurrent نوشته باشیم. (که ما مدیریت اجرای آن را بر عهده داشته باشیم)
این مثال نشان میدهد که چطور یک بخش سنگین در یک برنامه میتواند کل عملکرد آن برنامه را در Sequential Programming تحت تاثیر قرار دهد.
مثال – پایان ناتمام
فرض کنید کارفرما از شما خواسته تا برنامهای بنویسید که ۳ عدد از کاربر بگیرد و مشخص کند که کدام یک از بقیه بزرگتر است. همچنین کارفرما با تاکید زیاد از شما خواسته که در انتها پیامی چاپ کنید و از کاربر برای استفاده از این نرمافزار تشکر کنید.
این برنامه را میتوان به چهار بخش تقسیم کرد.
- اول – گرفتن ورودی ها از کاربر
- دوم – پیدا کردن بزرگترین عدد از بین ورودیها
- سوم – نمایش نتیجه
- چهارم – نمایش پیام تشکر
اگر شما خطاهای برنامه را مدیریت نکرده باشید و کاربر هم شیطنت کند و به جای اینکه عدد وارد کند، رشته وارد کند برنامه با خطا پایان مییابد. این بدین معنی است که در همان مرحله اول خطا ایجاد میشود و مراحل بعدی اجرا نخواهند شد پس پیام تشکر نیز چاپ نخواهد شد.
این مثال نشان میدهد که در برنامهنویسی sequential یکی از شروط لازم برای اجرای هر تسک این است که تسک قبلی به صورت کامل اجرا شده باشد.
مزایای Sequential Programming
سهولت اجرا و دیباگ
اجرا و عیبیابی برنامهها در برنامهنویسی sequential آنقدر راحت است که به عنوان اولین سبک برنامهنویسی به یک زبانآموز میآموزند.
سادگی معماری کد
برنامههایی که به سبک Sequential نوشته میشوند خوانایی بالاتری دارند زیرا اجرای آن یک فرایند خطی را دنبال میکند. به عبارتی میتوان گفت که بخشهای مختلف برنامه خطبهخط، یکی پس از دیگری اجرا میشوند. پس با نگاه به چند خط کد، راحتتر میتوان فهمید چه کاری پس از چه کاری انجام خواهد شد.
معایب برنامه نویسی sequential
مقیاس پذیری کمتر
در این نوع از برنامهنویسی نمیتوان همواره از همه منابع سیستم مانند RAM و CPU نهایت استفاده را برد. این نوع برنامهها را نمیتوان روی بیش از یک کامپیوتر اجرا کرد. یا نمیتوان بخشی از آن را روی یک کامپیوتر و بخشی دیگر را روی یک کامپیوتر دیگر اجرا کرد.
انعطاف پذیری کمتر
در صورتی که برنامه دارای بخشهای سنگین باشد، اجرای کل برنامه مختل شده و کل کار با سرعت کمتری انجام خواهد شد. همچنین اگر در بخشی از برنامه خطا داشته باشیم، احتمال اینکه بتوانیم به نحوی اجرای برنامه را با خروجی قابل قبول به پایان برسانیم کمتر است.
پارادایم Concurrent Programming
Concurrent Programming سبک متفاوتی از برنامهنویسی است که در آن، برنامهها به قسمتهای کوچکتری با قابلیت اجرای موازی یا همزمان تقسیم میشوند.
برای اینکه بتوانیم برنامههای خوبی به این سبک بنویسیم باید نوع تفکر و نگاه خود به برنامهنویسی را کمی تغییر دهیم که لازمه آن، رسیدن به درک خوبی از چگونگی عملکرد سیستمعامل در تقسیم تسکها و استفاده از منابع سیسیتم است.
مثال – پشت سر گذاشتن کابوس کامیون
مثال قبلی را در نظر بگیرید با این تفاوت که این بار جاده دو باند دارد. اکنون خودروها میتوانند بدون گیر افتادن پشت کامیون به مسیر خود ادامه داده و همه چیز در بهترین حالت خود پیش خواهد رفت.
دو بانده بودن جاده مانند این است که از دو هسته CPU یا از دو thread برای اجرای برنامه استفاده کنیم.
مثال – پردازش تصویر پس از دانلود
فرض کنید کارفرما از شما خواسته تا برنامهای بنویسید که بتواند لیستی را از روی اینترنت دانلود و پردازش کند که در آن عکس گربه وجود دارد یا خیر. این برنامه را میتوان به دو بخش تقسیم کرد:
- دانلود تصاویر از اینترنت
- پردازش تصاویر برای یافتن گربه
حتما پیش آمده که برای صرف زمان کمتر، چندین فایل را همزمان دانلود کرده باشید. در این مثال هم میتوان چندین فایل را همزمان با هم دانلود کرد. همچنین پردازش تصاویر را نیز میتوان به صورت موازی و همزمان انجام داد.
مزایای برنامه نویسی concurrent
مقیاس پذیری بیشتر
میتوان برنامه را به بخشهای کوچکتر تقسیم کرد و هر بخش را روی قسمتی از سختافزار اجرا کرد. حتی میتوان بخشی از برنامه را روی یک کامپیوتر مستقل دیگر تحت یک شبکه اجرا کرد.
سرعت اجرای بیشتر
به دلیل اجرای همزمان یا موازی برنامهها، اغلب سرعت رسیدن به خروجی نسبت به حالت sequential بیشتر است.
انعطاف پذیری بیشتر
اگر بخشی از برنامه که به صورت همزمان یا موازی با بخشهای دیگر در حال اجراست به خطا بخورد، راحتتر میتوان خطایش را مدیریت و رسیدن به خروجی نهایی را تضمین کرد.
معایب برنامهنویسی concurrent
پیچیدگی بالاتر
در این نوع برنامهنویسی کدها لزوما خطبهخط اجرا نمیشوند. یا ترتیب نوشتن کدها با ترتیبی که انتظار میرود لزوما یکسان نیست. به همین دلیل درک کدها در این نوع برنامهنویسی دشوارتر است.
همچنین این نوع برنامهنویسی نیاز به داشتن درک نسبتا خوبی از نحوه عملکرد سیستمعامل است. در صورتی که برنامهنویس با عملکرد سیستمعامل آشنا نباشد ممکن است برنامهای بنویسد که منابع را هدر دهد. مثلا برنامهای که نوشتنش با asyncio بهتر باشد را با multiprocessing بنویسد.
دیباگ کردن سخت تر است
به دلیل اینکه کدها لزوما خطبهخط اجرا نمیشوند، دیباگ کردن در این نوع برنامهنویسی مهارت خاص خود را میطلبد.
سوالات
- انواع پارادایم های برنامهنویسی از نظر زمان و ترتیب اجرای تسکها کداماند؟
- مزایا و معایب برنامهنویسی sequential چیست؟
- مزایا و معایب برنامهنویسی concurrent چیست؟
خلاصه
| ویژگی | برنامهنویسی Sequential | برنامهنویسی Concurrent |
| تعریف | اجرای تسکها به ترتیب یکی پس از دیگری در یک thread | اجرای تسکها به صورت موازی یا همزمان در چندین thread یا process |
| نوع اجرای همزمان | تکنخی (Single-thread) | چندنخی (Multithread) یا چندپردازشی (Multiprocessing) |
| مناسب برای | تسکهای ساده و خطی | تسکهای پیچیده و نیازمند پردازش موازی |
| مدیریت حافظه | ساده و مستقیم، حافظه مشترک ندارد | پیچیدهتر، ممکن است حافظه مشترک داشته باشد |
| پیچیدگی | سادهتر برای مدیریت و درک | پیچیدهتر برای مدیریت و نیاز به درک عمیقتر از سیستمعامل |
| دیباگ | سادهتر | دیباگ کردن سختتر به دلیل اجرای همزمان |
| مقیاسپذیری | کمتر | بیشتر |
| انعطافپذیری | کمتر | بیشتر |
| مثال کاربردی | گرفتن ورودی از کاربر و پردازش ساده | پردازش موازی تصاویر، عملیات شبکه |
| مزایا | – سهولت اجرا و دیباگ – سادگی معماری کد | – مقیاسپذیری بیشتر – سرعت اجرای بیشتر – انعطافپذیری بیشتر |
| معایب | – مقیاسپذیری کمتر – انعطافپذیری کمتر | – پیچیدگی بالاتر – دیباگ کردن سختتر |
| مثال توضیحی | – گیر افتادن خودروها پشت کامیون – برنامهای که خطاهایش مدیریت نشده | – جاده دو باند برای عبور خودروها – دانلود و پردازش موازی تصاویر |