ما دو نوع برنامه از نظر مصرف منابع داریم. برنامه های I/o bound و برنامه های cpu bound.
برنامه های I/o bound : برنامه هایی هستند که سرعت اجراشون به مدت زمانی که درگیر فعالیت ورودی خروجی هستند بستگی دارد. به طور کلی این برنامه ها اکثر زمانشون را صرف فعالیت ورودی و خروجی میکنند. مثلا برنامه downloader که وظیفه اش دانلود کردن یک فایل از اینترنت است یا برنامه ای که input از کاربر میگیره هر دو اکثر زمانشون را صرف فعالیت ورودی خروجی میکنند و جز دسته برنامه های I/o bound قرار میگیرند.
برنامه های cpu bound :
این برنامه ها اکثر زمانشون را صرف پردازش با cpu میکنند. مثلا برنامه ای که. ب.م.م دو عدد خیلی بزرگ را حساب میکنه.
خب multithreading پایتون قطعا مناسب برنامه های cpu bound ها نیست. چرا؟
ما زمانی میتونیم سرعت یک برنامه cpu bound را زیاد کنیم که بتوانیم از هسته های cpu استفاده بیشتر و بهتری کنیم . پردازش موازی میتونه عملکرد برنامه های cpu bound را بیشتر کنه و سرعت کار را بالاتر ببره.
از آنجایی که پایتون اجازه پردازش موازی را نمیده پس مناسب برنامه های cpu bound نیست.
ولی برنامه پایتون برای برنامه های I/o bound مناسب است. مثلا فرض کنید یه برنامه دارید که میخواهید همزمان یک داده از کاربر بگیره و یک داده ای را از یک socket بخوانه.
بدون multithreading :
بخش input گرفتن اجرا میشه و برنامه متوقف میشه تا کاربر چیزی را وارد کنه . بعد که وارد کرد میره سراغ خواندن از socket.
با multithreading :
دو تا thread میسازیم . Thread اول برای گرفتن input از کاربر و thread دوم برای خواندن داده از socket.
پایتون میتواند به صورت همروندی دو تا thread را اجرا کنه . از آنجایی که خیلی سریع بین thread ها سوییچ میکنه شما فکر میکنید دو تا کار به صورت همزمان اجرا میشه.
آیا پایتون برای برنامه های cpu bound راهکاری ندارد؟
راهکار بهینه کردن برنامه های cpu bound در پایتون multiprocessing است.
چندین process جدا بسازیم که برنامه را اجرا کنند. مثلا فرض کنید task1 و task2 را داریم که جفتشون cpu bound هستند. اگر هر دو تا task را تو یک فایل پایتون بنویسید و سعی کنید با multithreading برنامه را اجرا کنید چون پایتون اجازه پردازش موازی را نمیده در هر لحظه از زمان فقط یکی از task ها اجرا میشه. راهکار ساده اینه که با دو تا فایل پایتون برنامه را اجرا کنید.
در این حالت دو پروسه جدا با دو تا process id جدا داریم که هر پروسه یک GIL جدا دارند. و GIL های هر پروسه روی پروسه دیگری تاثیر نمیذارد. در واقع هر GIL باعث میشه thread های اون برنامه به صورت موازی اجرا نشه.
اطلاعات تکمیلی در مورد GIL در پایتون در این لینک وجود دارد
پس الان دو تا پروسه جدا یا همان دو تا فایل پایتون جدا میتونند به صورت موازی روی دو تا هسته جدا از cpu به صورت موازی اجرا بشوند.
پس مفهوم multiprocessing میگه چندین پروسه بساز که هر کدامشان بتوانند توسط سیستم عامل به صورت موازی اجرا بشوند. حالا اگر منابع کافی و هسته آزاد داشته باشه این پروسه ها را به صورت موازی اجرا میکنه و اگر نداشته باشه به صورت همروندی. اما در کل سیستم عامل تلاش میکنه به بهترین و سریعترین حالت ممکن پروسه ها را روی cpu اجرا کنه و نهایت استفاده را از cpu ببره.
اطلاعات کاملتر در این لینک