برنامه نویسی همگام و ناهمگام چیست

برنامه های نرم افزاری به دو دسته بلاک شدنی (Blocking Programming) هستند به طوری که با اجرا شدن یک واحد از برنامه، کل بخش های دیگر باید منتظر بمانند تا اجرای واحد قبلی به اتمام برسد. فرض کنید برنامه شما (مانند Office Word) چندین پردازش (فرایند) دارد.

در این حالت، با اجرا شدن یک فرایند، مابقی فرایندهای آن برنامه باید منتظر بمانند تا اجرای فرایند قبلی به پایان برسد. یکی از عواملی که باعث می شود اجرای یک فرایند زمان بر باشد، عملیات I/O است که می تواند از روی دیسک یا شبکه باشد.

آنچه که گفته شد را برنامه های بلاک شدنی یا همگام (Synchronous Programming) می گویند جایی که اجرای یک فرایند، اجرای دیگر فرایندها را به تعویق می اندازد. در برابر این شیوه، برنامه نویسی بلاک نشدنی (Nonblocking Programming) یا برنامه نویسی ناهمگام (Asynchronous Programming) وجود دارد.

در برنامه نویسی ناهمگام، اجرای یک فرایند منوط به پایان یافتن یک فرایند دیگر نیست، بلکه اگر فرایندی نیاز به عملیات I/O داشته باشد، در پس زمینه اجرا شده و سپس فرایند دیگر اجرا می شود و پس از آنکه عملیات I/O به پایان رسید، فرایند از پایان یافتن خود آگاه سازی می کند.

https://virgool.io/@pythonic/توابع-generator-و-کلمه-کلیدی-yield-rl8m1egndvav

مزیت برنامه نویسی همگام

مزیت اصلی برنامه نویسی ناهمگام برای بهبود کارایی (Performance) است جایی که نمی خواهیم کل عملکرد برنامه به خاطر یک فرایند سنگین مانند عملیات I/O متوقف شود. برنامه نویسی ناهمگام به گونه ای است که یک فرایند (نخ - Thread) از یک برنامه در پس زمینه اجرا می شود و پس از به اتمام رسیدن، نخ اصلی را از به پایان رسیدن خودش آگاه می کند.

توجه کنید در حین اجرای نخی که نیاز به I/O دارد، نخی دیگر شروع به اجرا شدن می کند و در همین حین فرایند (نخ) پس زمینه نیز اجرا می شود (مثلا خواندن از وب یا پایگاه داده یا یک فایل متنی روی دیسک)، سپس پاسخ را اطلاع می دهد.

کاربردی ساده از برنامه نویسی ناهمگام

فرض کنید در برنامه تان می خواهید تعدادی سطر را از پایگاه داده بخوانید. برای این منظور یک اتصال درون برنامه ایجاد کرده و سپس کوئری مورد نظر را از طریق واسط برنامه نویسی پایگاه داده و از درون برنامه ارسال می کنید.

آیا بخش های دیگر برنامه می توانند منتظر بدست آوردن سطرهای مربوط به پاسخ کوئری باشند؟ قاعدتا پاسخ خیر است. در اینجا می توانید توابع خواندن از پایگاه داده را به صورت ناهمگام (async) اجرا کنید زیرا که بدست آوردن (SELECTّ) از پایگاه داده یک عملیات I/O است.

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

https://fsprojects.github.io/SQLProvider/core/async.html
https://fsprojects.github.io/SQLProvider/core/async.html

به طور کلی در رایانه دو عملیات CPU-Bound و I/O-Bound وجود دارد. عملیات های CPU-Bound بسیار وابسته داشتن پردازنده هستند. در برابر این، عملیات های I/O نیازی به پردازنده ندارند و در مقابل برای اتمام خود، باید خواندن یا نوشتن را انجام دهند.

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

اکنون شما همین را درون یک پردازش (فرایند) در نظر بگیرید. اگر حتی فرایند چند نخی (Multithreading) باشد، یا اینکه برنامه به صورت چند پردازشی (Multiprocessing) باشد، اگر یک نخ یا فرایند از برنامه عملیات I/O انجام شود، کل آن برنامه معلق می شود. در سیستم عامل ها، زمان معلق شدن برنامه شما می بینید که مکان نما (Cursor) تغییر می کند. بنابراین در چنین مواردی نیاز است تا برنامه نویسی ناهمگام را استفاده کنیم.