برنامه نویسی

پایتون ناهمزمان – انجمن DEV

Summarize this content to 400 words in Persian Lang
این مقاله در ابتدا در اینجا ارسال شده است.

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

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

در مدل async، ترتیب اجرای وظایف در یک رشته با یکدیگر درهم می‌آیند. این ساده‌تر از حالت threaded است زیرا برنامه‌نویس همیشه می‌داند که وقتی یک وظیفه در حال اجرا است، وظیفه دیگری اجرا نمی‌شود. به آن چندوظیفه ای تعاونی می گویند. بعداً در مورد پیامدهای آن بحث خواهیم کرد. در حال حاضر، بدانید که این موضوع یک رشته ناهمگام را مشمول قفل مترجم جهانی (GIL) می‌کند. این یک mutex است که تضمین می کند که شرایط مسابقه وجود ندارد2. کار برای ایجاد چندین رشته، یک کتابخانه چند رشته ای است.

برنامه نویسی ناهمزمان برای فرآیندها/وظایف وابسته به منابع کامپیوتری خارج از CPU مرتبط است. به عنوان مثال، منابع HTTP نیاز به دسترسی به شبکه و باز کردن و بستن فایل ها نیاز به دسترسی به دیسک دارند. فراخوانی‌های دستورات همزمان را مسدود کردن (مسدود کردن تماس‌ها) می‌گویند، زیرا باید قبل از اجرای دستور بعدی اجرا شوند.3

در اینجا چند نمونه ساده وجود دارد که ظاهراً همین کارها را انجام می دهند. ما یک صف ایجاد می کنیم (به یاد داشته باشید، FIFO – first in first out)، که شامل وظایف (عملیات ساده) است، و سپس در صف تکرار می کنیم و وظایف را اجرا می کنیم. من اینها را در یک ساده پیچیده ام click CLI. برای دستورالعمل‌های نصب، README را در مخزن مربوطه ببینید.

در تابع sync، یک صف ایجاد می کنیم و یک تابع blocking worker را اجرا می کنیم که وظایف را از صف پردازش می کند. ما این کار را با استفاده از ماژول threading کتابخانه استاندارد و ماژول صف انجام می دهیم، که در آن هر کار یک مکث ساده با استفاده از time.sleep(1) برای شبیه سازی عملیات مسدودسازی این نشان می دهد که چگونه یک کارگر مسدود کننده که در یک رشته واحد اجرا می شود، وظایف را به صورت متوالی پردازش می کند.

در تابع async، یک را ایجاد می کنیم asyncio در صف قرار دهید و یک تابع کارگر غیر مسدود کننده را اجرا کنید که وظایف را از صف پردازش می کند. در این مورد، ما دو کارگر داریم که به طور همزمان کار می کنند و وظایف را از صف پردازش می کنند. ما از یک حلقه رویداد تک رشته ای برای اجرای همزمان کارگران استفاده می کنیم. این نشان می دهد که چگونه کارگران غیر مسدود کننده می توانند همزمان در یک رشته واحد در حین استفاده از آن اجرا شوند asyncio ماژول تابع خواب asyncio برای شبیه سازی زمان ممکن برای تکمیل عملیاتی مانند وظایف I/O-bound یا درخواست های شبکه استفاده می شود. به این کار چندوظیفه ای تعاونی می گویند4، جایی که حلقه رویداد به اجرا ادامه می دهد در حالی که وظیفه منتظر هر منبعی است که نیاز دارد. نمونه دیگری از این کار از طریق ژنراتورهای پایتون انجام می شود که از آنها استفاده می کنند yield (وظیفه بازده کنترل به حلقه)

HTTPx کتابخانه ای است که به ما یک رابط همگام و همگام می دهد. این می تواند راه خوبی برای نشان دادن تفاوت بین دو روش برای نوشتن کد همزمان در زمانی که وظایف محدود به CPU نیستند را به ما ارائه دهد. معمولاً درخواست‌های همزمان ساده را در کد پایتون می‌بینید که توسط بسته درخواست‌ها اجرا می‌شوند. تفاوت های کلیدی در مورد همزمان، توسعه پذیری شی httpx Client و پشتیبانی از http/2. در برنامه آزمایشی (نگاه کنید به cli/http.py، می توانید زمان واکشی همزمان داده های JSON را برای همه 30 تیم MLB در مقابل اجرای همزمان وظایف با استفاده از AsyncClient کلاس از httpx.

تفاوت های بین http/1.1 و http/2، که به چهار نکته اصلی خلاصه می شود: اولویت بندی محتوا، چندگانه سازی، فشار سرور و فشرده سازی هدر5. Multiplexing کارایی زیادی را برای توسعه دهندگان افزایش می دهد، زیرا یک ویژگی است که اجازه می دهد یک اتصال tcp بین سرور و کلاینت برقرار شود، جایی که مشتری چندین جریان را برای واکشی داده ها باز می کند. Server push به سرور اجازه می دهد تا پس از ارسال پیامی مبنی بر جزئیات محتوای ارسالی، داده ها را برای مشتری ارسال کند. فشرده سازی هدر اطلاعات اضافی هدر http را با استفاده از HPACK فشرده می کند. هنگامی که چندین درخواست انجام می شود، کاهش کوچک در اندازه بسته می تواند باعث کاهش تاخیر شود. از طرف دیگر اولویت بندی محتوا بیشتر به صفحات وب مربوط می شود، زیرا به مشتری اجازه می دهد انتخاب کند که کدام محتوا ابتدا بارگذاری شود (بین فایل های ثابت مانند CSS یا جاوا اسکریپت).

یک افسانه رایج این است که کد پایتون غیر همگام به دلیل همزمانی سریعتر از همزمان است. همانطور که قبلاً ذکر شد، این چندوظیفه ای مشارکتی در یک است مجرد نخ از آنجایی که thread ها همکاری دارند، CPU به طور یکنواخت توزیع نمی شود، زیرا اجرا باید توسط خود وظیفه واگذار شود به جای اینکه توسط یک گاورنر مانند هسته سیستم عامل قطع شود. کال پترسون این را هنگام محک زدن سرورهای همزمان و ناهمزمان نشان می دهد[^2.] او اشاره می کند که سرورهای async به تعداد زیادی کارگر نیاز ندارند زیرا می توانند از یک CPU استفاده کنند. این تأخیر ناشی از انجام یک کار است که آنها را کند می کند. او خاطرنشان می کند که توان عملیاتی با مقدار پایتون که با کد بومی جایگزین شده است تعیین می شود.

ادامه مطلب

Async Python از Hackernoon
500 خط یا کمتر: یک خزنده وب با Asyncio Coroutines

Concurrency ساختاریافته، که توسط جایگزینی برای asyncio، Trio (docs) استفاده می‌شود. این الگو در اینجا “الگوی مهد کودک” نامیده می شود که در آن نخ ها دارای نقاط ورود و خروج واضح هستند و در ساختارهایی به نام مهدکودک محصور می شوند. اینها تضمین می کنند که اجرای thread قبل از خروج فرآیند به پایان رسیده است.6

منابع

تصاویر کد از کربن.

Fonseca، R. (2012). برنامه نویسی غیر همگام [Class handout]. دانشگاه براون، CSCI 1680. ↩

“The Python GIL (Global Interpreter Lock) • آموزش Python Land.” سرزمین پایتون، 18 دسامبر 2021، https://python.land/python-concurrency/the-python-gil. ↩

گرینبرگ، میگل. Sync در مقابل Async Python: تفاوت چیست؟ https://blog.miguelgrinberg.com/post/sync-vs-async-python-what-is-the-fference. بازدید در 24 نوامبر 2024. ↩

“چند وظیفه ای مشارکتی.” ویکی پدیا، 31 ژانویه 2024. ویکی پدیا، https://en.wikipedia.org/w/index.php?title=Cooperative_multitasking&oldid=1201426758. ↩

«HTTP/2 در مقابل HTTP/1.1». Cloudflare.com، 2015، https://www.cloudflare.com/learning/performance/http2-vs-http1.1/. ↩

طراحی و موارد داخلی — مستندات Trio 0.27.0+dev. https://trio.readthedocs.io/en/latest/design.html#cancel-points-and-schedule-points. بازدید در 24 نوامبر 2024. ↩

این مقاله در ابتدا در اینجا ارسال شده است.

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

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

در مدل async، ترتیب اجرای وظایف در یک رشته با یکدیگر درهم می‌آیند. این ساده‌تر از حالت threaded است زیرا برنامه‌نویس همیشه می‌داند که وقتی یک وظیفه در حال اجرا است، وظیفه دیگری اجرا نمی‌شود. به آن چندوظیفه ای تعاونی می گویند. بعداً در مورد پیامدهای آن بحث خواهیم کرد. در حال حاضر، بدانید که این موضوع یک رشته ناهمگام را مشمول قفل مترجم جهانی (GIL) می‌کند. این یک mutex است که تضمین می کند که شرایط مسابقه وجود ندارد2. کار برای ایجاد چندین رشته، یک کتابخانه چند رشته ای است.

برنامه نویسی ناهمزمان برای فرآیندها/وظایف وابسته به منابع کامپیوتری خارج از CPU مرتبط است. به عنوان مثال، منابع HTTP نیاز به دسترسی به شبکه و باز کردن و بستن فایل ها نیاز به دسترسی به دیسک دارند. فراخوانی‌های دستورات همزمان را مسدود کردن (مسدود کردن تماس‌ها) می‌گویند، زیرا باید قبل از اجرای دستور بعدی اجرا شوند.3

در اینجا چند نمونه ساده وجود دارد که ظاهراً همین کارها را انجام می دهند. ما یک صف ایجاد می کنیم (به یاد داشته باشید، FIFO – first in first out)، که شامل وظایف (عملیات ساده) است، و سپس در صف تکرار می کنیم و وظایف را اجرا می کنیم. من اینها را در یک ساده پیچیده ام click CLI. برای دستورالعمل‌های نصب، README را در مخزن مربوطه ببینید.

در تابع sync، یک صف ایجاد می کنیم و یک تابع blocking worker را اجرا می کنیم که وظایف را از صف پردازش می کند. ما این کار را با استفاده از ماژول threading کتابخانه استاندارد و ماژول صف انجام می دهیم، که در آن هر کار یک مکث ساده با استفاده از time.sleep(1) برای شبیه سازی عملیات مسدودسازی این نشان می دهد که چگونه یک کارگر مسدود کننده که در یک رشته واحد اجرا می شود، وظایف را به صورت متوالی پردازش می کند.

کارگر سنکرون

در تابع async، یک را ایجاد می کنیم asyncio در صف قرار دهید و یک تابع کارگر غیر مسدود کننده را اجرا کنید که وظایف را از صف پردازش می کند. در این مورد، ما دو کارگر داریم که به طور همزمان کار می کنند و وظایف را از صف پردازش می کنند. ما از یک حلقه رویداد تک رشته ای برای اجرای همزمان کارگران استفاده می کنیم. این نشان می دهد که چگونه کارگران غیر مسدود کننده می توانند همزمان در یک رشته واحد در حین استفاده از آن اجرا شوند asyncio ماژول تابع خواب asyncio برای شبیه سازی زمان ممکن برای تکمیل عملیاتی مانند وظایف I/O-bound یا درخواست های شبکه استفاده می شود. به این کار چندوظیفه ای تعاونی می گویند4، جایی که حلقه رویداد به اجرا ادامه می دهد در حالی که وظیفه منتظر هر منبعی است که نیاز دارد. نمونه دیگری از این کار از طریق ژنراتورهای پایتون انجام می شود که از آنها استفاده می کنند yield (وظیفه بازده کنترل به حلقه)

کارگر ناهمزمان

HTTPx کتابخانه ای است که به ما یک رابط همگام و همگام می دهد. این می تواند راه خوبی برای نشان دادن تفاوت بین دو روش برای نوشتن کد همزمان در زمانی که وظایف محدود به CPU نیستند را به ما ارائه دهد. معمولاً درخواست‌های همزمان ساده را در کد پایتون می‌بینید که توسط بسته درخواست‌ها اجرا می‌شوند. تفاوت های کلیدی در مورد همزمان، توسعه پذیری شی httpx Client و پشتیبانی از http/2. در برنامه آزمایشی (نگاه کنید به cli/http.py، می توانید زمان واکشی همزمان داده های JSON را برای همه 30 تیم MLB در مقابل اجرای همزمان وظایف با استفاده از AsyncClient کلاس از httpx.

تفاوت های بین http/1.1 و http/2، که به چهار نکته اصلی خلاصه می شود: اولویت بندی محتوا، چندگانه سازی، فشار سرور و فشرده سازی هدر5. Multiplexing کارایی زیادی را برای توسعه دهندگان افزایش می دهد، زیرا یک ویژگی است که اجازه می دهد یک اتصال tcp بین سرور و کلاینت برقرار شود، جایی که مشتری چندین جریان را برای واکشی داده ها باز می کند. Server push به سرور اجازه می دهد تا پس از ارسال پیامی مبنی بر جزئیات محتوای ارسالی، داده ها را برای مشتری ارسال کند. فشرده سازی هدر اطلاعات اضافی هدر http را با استفاده از HPACK فشرده می کند. هنگامی که چندین درخواست انجام می شود، کاهش کوچک در اندازه بسته می تواند باعث کاهش تاخیر شود. از طرف دیگر اولویت بندی محتوا بیشتر به صفحات وب مربوط می شود، زیرا به مشتری اجازه می دهد انتخاب کند که کدام محتوا ابتدا بارگذاری شود (بین فایل های ثابت مانند CSS یا جاوا اسکریپت).

یک افسانه رایج این است که کد پایتون غیر همگام به دلیل همزمانی سریعتر از همزمان است. همانطور که قبلاً ذکر شد، این چندوظیفه ای مشارکتی در یک است مجرد نخ از آنجایی که thread ها همکاری دارند، CPU به طور یکنواخت توزیع نمی شود، زیرا اجرا باید توسط خود وظیفه واگذار شود به جای اینکه توسط یک گاورنر مانند هسته سیستم عامل قطع شود. کال پترسون این را هنگام محک زدن سرورهای همزمان و ناهمزمان نشان می دهد[^2.] او اشاره می کند که سرورهای async به تعداد زیادی کارگر نیاز ندارند زیرا می توانند از یک CPU استفاده کنند. این تأخیر ناشی از انجام یک کار است که آنها را کند می کند. او خاطرنشان می کند که توان عملیاتی با مقدار پایتون که با کد بومی جایگزین شده است تعیین می شود.

فهرست مطالب

ادامه مطلب

  1. Async Python از Hackernoon
  2. 500 خط یا کمتر: یک خزنده وب با Asyncio Coroutines
  3. Concurrency ساختاریافته، که توسط جایگزینی برای asyncio، Trio (docs) استفاده می‌شود. این الگو در اینجا “الگوی مهد کودک” نامیده می شود که در آن نخ ها دارای نقاط ورود و خروج واضح هستند و در ساختارهایی به نام مهدکودک محصور می شوند. اینها تضمین می کنند که اجرای thread قبل از خروج فرآیند به پایان رسیده است.6

منابع

تصاویر کد از کربن.


  1. Fonseca، R. (2012). برنامه نویسی غیر همگام [Class handout]. دانشگاه براون، CSCI 1680. ↩

  2. “The Python GIL (Global Interpreter Lock) • آموزش Python Land.” سرزمین پایتون، 18 دسامبر 2021، https://python.land/python-concurrency/the-python-gil. ↩

  3. گرینبرگ، میگل. Sync در مقابل Async Python: تفاوت چیست؟ https://blog.miguelgrinberg.com/post/sync-vs-async-python-what-is-the-fference. بازدید در 24 نوامبر 2024. ↩

  4. “چند وظیفه ای مشارکتی.” ویکی پدیا، 31 ژانویه 2024. ویکی پدیا، https://en.wikipedia.org/w/index.php?title=Cooperative_multitasking&oldid=1201426758. ↩

  5. «HTTP/2 در مقابل HTTP/1.1». Cloudflare.com، 2015، https://www.cloudflare.com/learning/performance/http2-vs-http1.1/. ↩

  6. طراحی و موارد داخلی — مستندات Trio 0.27.0+dev. https://trio.readthedocs.io/en/latest/design.html#cancel-points-and-schedule-points. بازدید در 24 نوامبر 2024. ↩

نوشته های مشابه

دیدگاهتان را بنویسید

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

دکمه بازگشت به بالا