اول از همه باید بگم که تو این مقاله از مفاهیمی استفاده شده که شاید برای خیلی ها تازگی داشته باشه, واسه همین سعی کردم اول یه توضیح ساده راجع به اون ها بدم و بعدش بحث اصلی رو شروع کنم:
اعمال هم زمان در پایتون (بخش اول)
اجرای هم زمان وظایف
کارایی یک نرم افزار فقط زمانی به بالاترین حد خود می رسه که بتونه به درستی از منابع سخت افزاری سیستم استفاده کنه. وقتی در حیطه ی نرم افزار صحبت از منابع سخت افزاری می شه اصولا منظور ما پردازنده و حافظه هست. برنامه ها به هنگام اجرا در پروسه ها یا فرآیندها طبقه بندی می شن. به این صورت که سیستم عامل مقداری از حافظه رو به هر فرآیند تخصیص میده و پردازنده اقدام به پردازش اون فرآیند در حافظه می کنه. به حالت عادی هر پردازنده در هر زمان فقط می تونه یه فرآیند را مورد پردازش قرار بده اما سیستم عامل با زمان بندی مناسب باعث می شه قدرت پردازنده بین تمام فرآیندها تقسیم بشه و چندین فرآیند بتونن به طور هم زمان مورد پردازش قرار بگیرن. به یک همچین عملی ” multi-tasking” یا “چند وظیفه ای” گفته میشه.
کارایی یک نرم افزار فقط زمانی به بالاترین حد خود می رسه که بتونه به درستی از منابع سخت افزاری سیستم استفاده کنه. وقتی در حیطه ی نرم افزار صحبت از منابع سخت افزاری می شه اصولا منظور ما پردازنده و حافظه هست. برنامه ها به هنگام اجرا در پروسه ها یا فرآیندها طبقه بندی می شن. به این صورت که سیستم عامل مقداری از حافظه رو به هر فرآیند تخصیص میده و پردازنده اقدام به پردازش اون فرآیند در حافظه می کنه. به حالت عادی هر پردازنده در هر زمان فقط می تونه یه فرآیند را مورد پردازش قرار بده اما سیستم عامل با زمان بندی مناسب باعث می شه قدرت پردازنده بین تمام فرآیندها تقسیم بشه و چندین فرآیند بتونن به طور هم زمان مورد پردازش قرار بگیرن. به یک همچین عملی ” multi-tasking” یا “چند وظیفه ای” گفته میشه.
multi-tasking این امکان رو میده که چندین برنامه به صورت همزمان اجرا بشن. برای مثال می تونید همزمان با اجرای مرورگر firefox یک فیلم رو هم تو mplayer مشاهده کنید. در سیستم عاملی مثل DOS این امکانات فراهم نبود و فقط یه برنامه در هر زمان می تونست اجرا بشه. در ضمن اگه از چند پردازنده استفاده کنیم و یا پردازنده ی دستگاهمون چند هسته ای باشه کارایی مکانیزم multi-tasking به بالاترین حد خودش می رسه.
تا اینجای کار فهمیدیم که سیستم عامل می تونه با استفاده از multi-tasking چند تا عمل رو در یک زمان انجام بده و با حداکثر استفاده از قدرت پردازنده باعث بشه کارایی برنامه ها بالاتر بره. اما نکته ی قابل توجه اینه که ما می تونیم multi-tasking را در سطح برنامه ی خودمون هم اعمال کنیم. از اونجایی که هر برنامه کامپیوتری از زیربرنامه های مختلف تشکیل میشه ما می تونیم در صورت نیاز اجرای چند زیر برنامه رو به صورت هم زمان انجام بدیم. اما ممکنه این سوال پیش بیاد که این کار چه نفعی می تونه داشته باشده. در جواب این سوال میشه به دو منفعت اساسی این روش استفاده کرد:
1. برنامه ی ما می تونه چند عمل رو در یک زمان انجام بده. مثلا در نظر بگیرید که قراره برنامه ای بنویسیم که می خواد دو جفت عدد رو با هم جمع کنه و در آخر حاصل جمع هر دو جفت رو به خروجی بفرسته. پیاده سازی معمولی این برنامه می تونه به صورت زیر باشه:
جمع جفت اول رو انجام بده.
جمع جفت دوم رو انجام بده.
حاصل جمع جفت اول رو به خروجی بفرست.
حاصل جمع جفت دوم رو به خروجی بفرست.
در اینجا اعمالی که برنامه انجام می ده به ترتیب صورت میگیره. اما مساله اینه که چرا وقتی پردازنده ی ما این قدرت رو داره که بخواد تمام اعمال رو با هم انجام بده, ما از این مزیت استفاده نکنیم؟ پس برنامه رو با استفاده از multi-tasking به صورت زیر بازنویسی می کنیم:
جمع جفت اول و دوم را انجام بده.
حاصل جمع این دو جفت را به خورجی بفرست.
جمع جفت اول رو انجام بده.
جمع جفت دوم رو انجام بده.
حاصل جمع جفت اول رو به خروجی بفرست.
حاصل جمع جفت دوم رو به خروجی بفرست.
در اینجا اعمالی که برنامه انجام می ده به ترتیب صورت میگیره. اما مساله اینه که چرا وقتی پردازنده ی ما این قدرت رو داره که بخواد تمام اعمال رو با هم انجام بده, ما از این مزیت استفاده نکنیم؟ پس برنامه رو با استفاده از multi-tasking به صورت زیر بازنویسی می کنیم:
جمع جفت اول و دوم را انجام بده.
حاصل جمع این دو جفت را به خورجی بفرست.
2. کارایی برنامه بالاتر میره. در مثالی که زدم مشاهده کردید که با استفاده ی بهینه تر از قدرت پردازنده, مراحل کاری برنامه ی ما کاهش پیدا کرد. این امر علاوه بر اینکه اجرای برنامه ی ما رو سریعتر میکنه باعث میشه برنامه بهتر از منابع سخت افزاری ای که در اختیارش گذاشته میشه استفاده کنه و بی خود اون ها رو هدر نده.
حالا که با مزیت های multi-tasking آشنا شدیم باید ببینیم که جه جوری می تونیم از این شیوه تو برنامه ها مون استفاده کنیم. برای پیاده سازی multi-tasking در برنامه ها دو راه حل اصلی وجود داره:
1. multi-processing (چند پروسه ای)
multi-processing برای پیاده سازی multi-tasking از پروسه ها یا همون فرآیندها استفاده میکنه. مثلا وقتی می خواهید دو زیر برنامه در برنامه ی شما به طور هم زمان اجرا بشه, multi-processing دو پروسه ی جداگانه ایجاد میکنه و از سیستم عامل مقداری حافظه برای اون ها قرض میگیره. بعدش هر کدوم از این زیربرنامه ها رو داخل این پروسه ها پردازش میکنه. بعد از اینکه پردازش تموم شد مقدار حافظه ای که قرض گرفته بود رو آزاد میکنه و نتیجه ی پردازش رو به برنامه بر میگردونه. دقت کنید که هر پروسه یا فرآیند مخصوص نگه داری یک برنامه مستقل هستش, یعنی وقتی برنامه ی شما این دو پروسه ی جدید رو ایجاد میکنه در واقع داره دو برنامه ی جدید رو به سیستم عامل معرفی میکنه. حتما شما هم فکر می کنید که این شیوه با اینکه عملیات هم زمان سازی رو انجام میده ولی اونطور که باید و شاید از لحاظ سخت افزاری به صرفه نیست. که البته این موضوع هم تا حدودی به معماری سیستم عاملتون بر می گرده.
multi-processing برای پیاده سازی multi-tasking از پروسه ها یا همون فرآیندها استفاده میکنه. مثلا وقتی می خواهید دو زیر برنامه در برنامه ی شما به طور هم زمان اجرا بشه, multi-processing دو پروسه ی جداگانه ایجاد میکنه و از سیستم عامل مقداری حافظه برای اون ها قرض میگیره. بعدش هر کدوم از این زیربرنامه ها رو داخل این پروسه ها پردازش میکنه. بعد از اینکه پردازش تموم شد مقدار حافظه ای که قرض گرفته بود رو آزاد میکنه و نتیجه ی پردازش رو به برنامه بر میگردونه. دقت کنید که هر پروسه یا فرآیند مخصوص نگه داری یک برنامه مستقل هستش, یعنی وقتی برنامه ی شما این دو پروسه ی جدید رو ایجاد میکنه در واقع داره دو برنامه ی جدید رو به سیستم عامل معرفی میکنه. حتما شما هم فکر می کنید که این شیوه با اینکه عملیات هم زمان سازی رو انجام میده ولی اونطور که باید و شاید از لحاظ سخت افزاری به صرفه نیست. که البته این موضوع هم تا حدودی به معماری سیستم عاملتون بر می گرده.
2. multi-threading (چند نخی)
multi-threading شیوه ی دیگری برای هم زمان سازی اجرای زیربرنامه هاست که سریعتر و سبک تر از multi-processing عمل میکنه. تو این شیوه به جای استفاده از پروسه ها از “نخ ها” (threads) استفاده میشه. نخ ها جریان های شناور داخل پروسه ها هستند که عملیات برنامه رو تقسیم بندی میکنند. به حات عادی هر پروسه فقط یک نخ ایجاد میکنه پس در هر زمان فقط یک عملیات داخل هر پروسه پردازش می شه. multi-threading می تونه چندین نخ را به صورت هم زمان ایجاد کنه تا با این کارهر پروسه بتونه میزان پردازش بیشتری را از پردازنده ی دستگاه درخواست کنه. در این روش به جای اینکه چند پروسه ی جدید ( یا چند برنامه ی جدید ) در حافظه ایجاد بشه, چند نخ جدید در هر پروسه ایجاد میشه و نخ ها از حافظه ای که مختص به همون پروسه هستش استفاده میکنن. این روش سریعتر و بهینه تر از روش multi-processing هست. در ضمن در multi-threading چون نخ ها از حافظه ی جداگانه استفاده نمی کنند, می توانند به راحتی با هم ارتباط داشته باشند و داده هایشان را با هم به اشتراک بگذارن؛ این کاریه که در شیوه ی multi-processing به راحتی قابل انجام نیست چون هر پروسه از حافظه های جداگانه استفاده میکند.
multi-threading شیوه ی دیگری برای هم زمان سازی اجرای زیربرنامه هاست که سریعتر و سبک تر از multi-processing عمل میکنه. تو این شیوه به جای استفاده از پروسه ها از “نخ ها” (threads) استفاده میشه. نخ ها جریان های شناور داخل پروسه ها هستند که عملیات برنامه رو تقسیم بندی میکنند. به حات عادی هر پروسه فقط یک نخ ایجاد میکنه پس در هر زمان فقط یک عملیات داخل هر پروسه پردازش می شه. multi-threading می تونه چندین نخ را به صورت هم زمان ایجاد کنه تا با این کارهر پروسه بتونه میزان پردازش بیشتری را از پردازنده ی دستگاه درخواست کنه. در این روش به جای اینکه چند پروسه ی جدید ( یا چند برنامه ی جدید ) در حافظه ایجاد بشه, چند نخ جدید در هر پروسه ایجاد میشه و نخ ها از حافظه ای که مختص به همون پروسه هستش استفاده میکنن. این روش سریعتر و بهینه تر از روش multi-processing هست. در ضمن در multi-threading چون نخ ها از حافظه ی جداگانه استفاده نمی کنند, می توانند به راحتی با هم ارتباط داشته باشند و داده هایشان را با هم به اشتراک بگذارن؛ این کاریه که در شیوه ی multi-processing به راحتی قابل انجام نیست چون هر پروسه از حافظه های جداگانه استفاده میکند.
موارد لازم برای شروع کار
نکته ای که اینجا لازمه بگم اینه که اگه بخواین از multi-tasking تو برنامه هاتون استفاده کنید اول باید سیستم عاملی داشته باشید که از multi-tasking پشتیبانی کنه ( که تقریبا همه سیستم عامل ها این کار رو می کنن) و در ضمن زبان برنامه نویسی ای که برای نوشتن برنامه استفاده میکنید باید قابلیت پیاده سازی شیوه های multi-processing و multi-threading رو داشته باشه. (توجه کنید که ارجحیت با multi-threading هستش)
زبان هایی مثل Java, C#, Python و یا Ruby به صورت درونی از این شیوه ها پشتیبانی میکنند. زبان هایی مثل ++C هم هستن که این قابلیت ها رو به صورت درونی ندارن ولی می تونن از این شیوه ها استفاده کنن. البته زبان هایی هم مثل PHP وجود دارن که اصلا همچین چیزهایی رو پیاده سازی نکردن (اگه اشتباه میکنم گوشزد کنین تا اصلاح بشه)
شاید این سوال واستون پیش اومده باشه که چه طور ممکنه C و++C به صورت درونی multi-tasking رو پیاده سازی نکرده باشن ولی بیشترین استفاده از multi-tasking در همین زبان باشه؟ جواب خیلی ساده اس. از اونجایی که این دو زبان جزو زبان های سطح میانی به حساب میان و اصولا برای کارهای سیستمی استفاده میشن, در استاندارد اون ها پیش بینی شده که ممکنه برنامه های C و ++C روی سیستم عاملی استفاده بشن که از multi-tasking پشتیبانی نکنه! و یا شاید اصلا نیاز به multi-tasking وجود نداشته باشه و یا….. به همین خاطر این دو زبان طبق استاندارد هاشون به صورت درونی از multi-tasking پشتیبانی نمی کنن و پیاده سازی اون رو وظیفه ی سازنده های کامپایلر و یا کتابخونه های اضافی می دونن. البته لازم به گفتنه که استاندارد آینده ی ++C که به C++0x مشهور هستش, سازنده های کامپایلر رو مجبور میکنه که عملیات هم زمان سازی رو به صورت دورنی در++C قرار بدن که با این کار ++C رو یک قدم به ساخت برنامه های کاربردی نزدیک تر می کنن و یک قدم هم اونو از مسایل سیستمی دورتر میکنن و با این حساب در آینده باز هم این C هستش که به عنوان یه زبان سیستمی حرف اول رو می زنه.
از معدود زبان های سطح بالا که کاملا multi-tasking ( یا شاید دیگه بهتر باشه بگیم multi-threading ) رو پیاده سازی کردن Java هستش. اکثر زبان ها اون رو به طور کامل و همه جانبه پیاده سازی نکردن که از جمله ی اون ها میشه به Python , Ruby و یا حتی #C اشاره کرد.
حالا که با اصول و مفاهیم اولیه کار آشنا شدیم می تونیم در بخش دوم مقاله به مبحث اصلی خودمون یعنی “اعمال همزمان در پایتون) بپردازیم.









سلام
مطلب کامل و جامعی در زمینه خودش بود
تعاریف نیز بسیار سلیس و روان بود
موفق باشی
سلام
من می تونم از شما درخواست کمک کنم؟ تحقیقی در رابطه با multi tasking برای درس ریزپردازنده دارم. می تونید منابع فارسی به من معرفی کنید؟
والا چی عرض کنم… من خودم همش به مرور زمان توی سایت های برنامه نویسی خارجی با این مسائل آشنا شدم… راستشو بخوای اگه همین الآن یه منبع انگلیسی هم بخوای من شاید خوب نتونم بهت معرفی کنم حالا چه برسه به فارسی…. اما یه چیزو مطمئن هستم اونم اینه که هر کتاب فارسی که در مورد “سیستم عامل” بحث کرده باشه حتما یه بخشی هم در این زمینه تو خودش داره… اما تو سایت های خارجی که بخوای بچرخی زیاده…