آشنایی با Twisted مقدمه (قسمت اول)

آموزش Twisted

با نام خدا و سلام، سعی دارم در این مطلب به صورت کامل به Twisted در پایتون بپردازم، احتمال زیاد در چند قسمت این مبحث را در خدمت علاقه مندان به Twistedباشم و امید به خدا پس از پایان بخش آموزش متنی، ویدئویی آموزش پیرامون مبحث Twisted نیز خواهم ساخت.

مراجع اصلی این مبحث از قرار زیر هستند :

خب به صورت مستقیم در ابتدای کار دنبال Twisted نمی ریم و اول یه مقدار مقدمه میگم و بعدش قدم به قدم در مورد ویژگی های Twisted نیز صحبت خواهیم کرد. سعی می کنم مباحث کد نویسی همگی با مثال های روشن مطرح بشوند تا به کد نویسی و فهم مطلب کمک بیشتری بکند.

شروع

اول از همه Twisted سرگرم کننده خواهد بود، در ابتدا به عنوان بازی شروع به کار کرد، ابتدا به صورت تجاری در بازی ها استفاده میشد، در حال حاضر نیز هست.

twisted پلتفرمی جهت توسعه اپلیکیشن های اینترنت می باشد. در حالی که پایتون به خودی خود زبانی بسیار قدرتمند میباشد، منتهی امکانات بسیاری هستند که در مقابل دیگر زبان هایی که روی آنها بسیار کار کرده اند دارای کمبود است.

Twisted نیز یک کتابخانه یا فریمورک خوبی است که در حال پیشرفت است و بستگی به استفاده و رفتار با آن هم اکنون عالی ام هست.

یکی از نکات اصلی اینجاست که Twisted کتابخانه ای Opne Source می باشد.

تا اینجای کار، Twisted موتور نتوورکینگ ای می باشد که به زبان پایتون نوشته شده و تعدادی از پروتوکل های لایه های Application و Transport از جمله TCP، UDP، SSL/TLS، HTTP، IMAP، SSH، IRCو FTP را پشتیبانی می کند.

کتابی که در مراجع بالا نامش را آوردم، یه اصطلاح قشنگی برای Twisted آورده و نوشته همانند ابزار هایی که روشون نوشته “Batteries-included” به معنی (همراه با محصول باطری هم ارائه شده است)، توئیستد نیز با پیاده سازی های کلاینت و سروربرای تمام پروتکل های خودش ارائه شده است که کانفیگ و دپلوی کردن را آسان کرده است.

چرا از Twisted استفاده کنیم ؟

  • قدرت گرفته از پایتون
  • بر مبنای اسنکرون (ناهمگام – Asynchronous) و رویداد (event-base)
  • تمام ویژگی های شبکه را دارد
  • متن باز (Open Source)
  • انجمنی قوی به عنوان پشتیبان دارد
  • پلتفرمی دوست دار اجتماع (Integration friendly platform)

نصب Twisted

برای نصب من روی لینوکس اقدام کردم و روی virtualenv جدید به نام test-twisted-env نصب را انجام دادم:

python3 -m venv test-python-env
cd test-python-env
source test-python-env/bin/activate
pip install twisted

تست نصب موفق Twisted :

تست نصب Twisted

از آغاز شروع می کنیم 🙂

خب من همچون مرجع اولی که ابتدای این مطلب معرفیش کردم، ابتدا به استفاده از Twisted نمیپردازم و به جایش از برنامه های ساده نوشته شده به زبان پایتون جهت توضیح روش کار سیستم های ناهمگام استفاده می کنم.

گاماس گاماس به جلو پیش می ریم، اگر دوست داشتید می توانید این قسمت ها را رد کنید و جلوتر در اینجا یکدفعه به قسمت های کار با Twisted بپردازید. همچنین وقتی که به Twisted رسیدیم نیز از جنبه های بسیار سطح پایین Twisted که به صورت معمول در برنامه نویسی های روزانه استفاده نمی شوند شروع خواهیم کرد

Twisted به شدّت سیستمی انتزاعی هست، و زمانی که از آن جهت حل مسائل استفاده می کنید بر شما نفوذ وحشتناکی خواهد داشت.

پشگفتار

مدل ها – Models

با مروی بر دو مدل آشنا به ترتیب در مقایسه با مدل ناهمگام شروع می کنیم.

به روشی روشن ما برنامه ای را فرض می کنیم که دارای سه وظیفه – task متفاوت است و جهت تکمیل شدن برنامه، باید هر سه وظیفه – task انجام شوند. بعدا روی هر وظیفه تمکرز خواهیم کرد، ولی در حال حاضر چیزی در موردشان نمی گیم جز این که برنامه باید آنها را انجام دهد. (توجه داشته باشید در اینجا از وظیفه-task نام بردیم ولی نه به معنی «چیزی که نیاز است تا انجام شود»)

اولین مدلی که به آن می پردازیم، مدل همگام تک نخی (single-threaded synchronous model) می باشد که در تصویز زیر مشخص می باشد:

تصویر ۱ : مدل همگام

این ساده ترین استایل برنامه نویسی می باشد. هر Task در یک زمان انجام می شود، که هر کدوم قبل از این که بعدی شروع بشود تمام می شوند. اگر Task ها همیشه در ترتیبی معین انجام شوند، اجرای Taskآخر نشانه از این است که Task ها قبلی بدون هیچ اروری به طور کامل انجام شده اند.

مدل همگام را می توان با مدلی دیگر به نام مدل نخ (Threaded model) که رد تصویر زیر نشان داده شده مقایسه کرد:

تصویر دوم : مدل Threded

در این مدل هر Task تحت کنترل یک thread مجزی، انجام می شود. نخ ها (Threads) توسط سیستم عامل مدیریت می شوند

نکته اینجاست که در مدل threaded جزییات اجرا (execution) توسط OS مدیریت می شود و برنامه نویس بسادگی فکر می کند بر حسب جریان ساختار های مستقل (independent instruction streams) به صورت همزمان انجام می شود.

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

بعضی از برنامه ها پیاده سازی موازی کاری را با استفاده از چند فرآیند (Process) بجای استفاه از نخ (Thread) انجام می دهند. گرچه جزییات برنامه نویسی اش متفاوت است، اما برای هدف ما، این روش نیز همچون مدل دوم می باشد.

حال به معرفی مدل ناهمگام در تصویر سوم می پردازیم:

تصویر سوم: مدل ناهمگام

در این مدل، task ها در میان یکدیگر (Interleaved) قرار می گیرند، منتهی یک thread برای کنترل وجود دارد.

این مدل از مورد Threaded ساده تر است چرا که برنامه نویس همواره می داند که چه زمانی یه task در حال اجرا است و task دیگری خیر. گرچه در سیستم های single-processor برنامه ی Threaded نیز در الگوی در میان گذاری (Interleaved) اجرا می شود و برنامه نویس باید همچنان به تصویر دوم فکر کند نه تصویر سوم تا مبادا برنامه وقتی به سیستم multi-processorانتقال میابد اشتباه کار کند.

تفاوت دیگری نیز بین مدل های ناهمگام (asynchronous) و Threaded وجود دارد. در سیستم های Threaded تصمیم اینکه یک thread را معلق (suspend) کنند و Thread دیگری را در حال اجرا در بیاورند در حقیقت خارج از کمترل برنامه نویس می باشد. بجایش در اختیار سیستم عامل است و برنامه نویس باید این رو در نظر بگیره که یک thread می تواند در هر زمانی معلق شده و با Thread دیگری جایگزین شود. در مقابلش در سیستم های ناهمگام، یک task به کارش ادامه می دهد تاجایی که خودش به صراحت کنترل را رها کرده و به taskدیگری بدهد. این دومین سادگی نسبت به مورد Thrededمی باشد.

توجه داشته باشید که امکان ترکیب مدل های Thread و ناهمگام در یک سیستم وجود دارد

انگیزش

خب تا اینجا دیدیم که مدل ناهمگام ساده تر از مدل Threded می باشد، یکی به این دلیل که فقط یک جریان ساختاری وجود دارد و Task ها خودشان به صراحت کنترل را رها کرده به جای آنکه به طور دلخواه تعلیق شوند. اما مدل ناهمگام به وضوح نسبت به مدل همگام پیچیده تر است. برنامه نویس باید هر task را به ترتیبی از مراحل کوچکتر سازمان دهی کند که به صورت در میان یکدیگر (interleave) اجرا شوند (به شکل سوم توجه کنید که task1 که سبز رنگ می باشد به قطعات کوچکتر به صورت سری باید تقسیم شود تا در میان دیگر task ها قرار گیرد.)

همچنین اگر یک task از خروجی taskدیگری استفاده می کند، task وابسته باید نوشته شود تا ورودی اش را به عنوان توالی ای از بیت ها بجای همشان با هم قبول کند. چون در حقیقت موازی سازی وجود ندارد، اینطور از نمودار ها دیده می شود که یک برنامه ناهمگام نسبت به همگام بیشتر طول می کشد تا انجام شود.

پس چرا باید استفاده از مدل ناهمگام را انتخاب کنیم؟

حداقل دو تا دلیل وجود دارد:

اولی ، اگر یکی یا چند تا از task ها وابسته به intefrace از سمت کاربر باشند، با استفاده از interleave (د رمیان هم گذاری) کردن taskها با یکدیگر، سیستم همچنان که دیگر کارهایش را دارد در پشت زمینه (background) انجام می دهد می تواند برای ورودی های کاربر نیز پاسخگو باشد. بنابر این درحالی که taskهای پشت زمینه ممکن سریعتر انجام نشوند، منتهی سیستم داره همچنان کار می کنه و کاربر می تواند با لذت از آن استفاده کند.

با این وجود ، شرایطی وجود دارد که یک سیستم ناهمگام به سادگی از یک سیستم همگام ،به طرز چشمگیری به انجام کلیه task های خود در یک زمان کوتاه تر عمل می کند. این شرایط زمانی رُخ می دهد که task ها مجبور به انتظار یا بلوک شدن (block) باشند، در تصویر ۴ نشان داده شده است:

تصویر چهارم: بلاک شدن در برنامه همگام
blocking in a synchronous program

در تصویر فوق، قسمت های خاکستری پریود های زمانی را نشان می دهد که taskمشخصی در انتظار (یا بلاک) است و در نتیجه هیچ پیشروی نخواهد داشت.

چرا یک Task بلوکه می شود؟ از دلایل رایج این هست که منتظر انجام یک عمل I/O جهت انتقال یا دریافت داده از ابزار خارجی می باشد. در نتیجه یه برنامه همگام که دارای عملیان I/O زیادی باشد زمانی بیشتری را در انتظار یا حالت بلوکه خواهد بود.

توجه کنید که تصور چهارم یه جورایی شبیه به تصویر سوم است، شبیه به برنامه ناهمگام. این یک سازگاری و انطباق محسوب نمی شود.

ایده ی بنیادی پشت مدل ناهمگام نسبت به مدل همگام در اینجاست که زمانی که Task بلوکه می شود، دیگر Taskها به فعالیت خود ادامه می دهند که منجر به پیشروی کلی برنامه می شود. در نتیجه برنامه ناهمگام تنها زمانی بلوکه می شود که هیچ task ای نتواند پیشروی داشته باشد، به همین دلیل به برنامه ناهمگام برنامه بدون-بلاک نیز گفته می شود.

در مقایسه با مدل همگام، مدل ناهمگام در زمان های زیر بهتر عمل می کند:

  1. تعداد Taskها زیاد باشد و در نتیجه همواره حداقل یه taskداریم که بتواند پیشروی داشته باشد.
  2. task ها عملیات I/O ی زیادی را داشته باشند که منجر می شود برنامه همگام زمان زیادی را بلوکه شود در حالی که دیگر taskها می توانستند به عمل خود ادامه دهند.
  3. taskها به طور کلی نسبت به هم مستقل باشند و درنتیجه کمترین مقدار نیاز به اتصالات میان task ای وجود دارد (task های کمتری برای انجام شدن نیاز به انجام taskدیگری دارند)

این شرایط همچنین به طور کلی یک سرور شبکه تقریبا شلوغی را در محیط های کلاینت-سرور شرح می دهد. هر task نشان دهنده یک درخواست کلاینت با I/O در فرم دریافت درخواست و ارسال جواب خواهد داشت. و درخواست های کلاینت به طور گسترده مستقل هستند. در نتیجه یک سرور شبکه، کاندید مناسبی برای مدل های ناهمگام می باشدو این دلیلی است که چرا Twisted اولی و جلوترین کتابخانه نتوورکینگ می باشد.

پیش به جلو و بالا

تا اینجا مقدمه ای مطرح شد، در قسمت دوم تعدادی برنامه های شبکه خواهیم نوشت، هر دو دسته blocking و non-blocking به روش ساده و بدون استفاده از twisted خواهیم نوشت تا روش و چگونگی حقیقی کار کردن برنامه های نا همگام پایتون را درک کنیم.