وقتی واژهی Synchronous را در دیکشنری جستجو میکنید، چیزی که دستگیرتان میشود احتمالا این معنی است: همزمان.
و به تناسب، برای واژهی Asynchronous هم با معنی «غیر همزمان» مواجه خواهید شد.
اگر در حال خواندن این نوشته هستید، احتمالا شما هم مثل من به این نتیجه رسیدهاید که این معانی نمی توانند مفهوم این دو واژه را بدرستی منتقل نمایند. وقتی می خواهیم دربارهی این دو واژه در برنامهنویسی صحبت کنیم، متوجه خواهیم شد که «زمان» فقط یکی از فاکتورهایی است که در این موضوع دخیل است؛ حتی در خیلی از اوقات، قضیه «زمان» واقعا در اولویت نیست!
بیشتر نوشته های موجود در اینترنت نیز هنگام توضیح این دو مفهوم، به سرعت با عوامل جانبی مانند چگونگی پیادهسازی اینها در فلان زبان یا فلان فریم ورک خاص مخلوط میشوند و هیچوقت به درستی درکی از خود این مفاهیم صورت نمی گیرد. نتیجه این میشود که برنامهنویسها از چنین قابلیتهایی در کدهایشان استفاده می کنند، بدون اینکه واقعا اصل داستان را بدانند.
من در این نوشته میخواهم به شیوهی خودم این دو مفهوم پر استفاده را توضیح دهم؛ شاید این نوشته بتواند سودمند واقع شود.
برای لحظهای، موضوع «زمان» را به طور کامل از فکر خود بیرون کنید! بیاید از زاویه دیگری به مفهوم Synchronous نگاه کنیم؛
وقتی میگوییم کدهای ما Synchronous است، در حقیقت داریم درباره «ترتیب اجرای» کدها حرف میزنیم! به شکلی که این «ترتیب اجرا»، برابر با همان «ترتیب نگارش» کدهایمان باشد.
بنابراین «زمان» تنها فاکتور دخیل در Synchronous بودن نیست. در این مفهوم، «مکان» کدها و اینکه آنها را به چه شیوهای نوشته باشیم نیز از اهمیت برخوردار است.
وقتی میگوییم کدهای ما حالت Synchronous دارند، به این معنی است که ترتیب اجرای آنها پشت سر هم و به شکلی کاملا قابل پیشبینی اتفاق میافتد. فرضا شبه کد زیر را در نظر بگیرید:
var a = 10; var f = file.open("names.txt"); var names = f.read(); print names; print a + 2;
ما انتظار انجام یک سری از وظایف را از کامپیوتر داشتیم. با توجه به آن انتظارات، به ترتیب خاصی کدهایمان را نگارش کردیم و از بالا به پایین دستوراتی که کامپیوتر باید اجرا کند را برایش شرح دادهایم و انتظار داریم که این دستورات به همان ترتیبی که نگارش شدهاند اجرا شوند:
10
در متغیر a
ریخته شود.names.txt
باز شود و ارجاعی در آن در متغیر f
ریخته شود.f
خوانده شود و به طور رشتهای در متغیر s
قرار بگیرد.s
قرار دارد چاپ شود.a + 2
نیز در خروجی چاپ شود.در مثال بالا، ما به عنوان برنامهنویس چنین رویهای را دنبال کردیم:
کامپیوتر نیز اجرای کدهای ما را به شکلی قابل پیش بینی انجام خواهد داد. فرضا چاپ کردن محتوای فایل، حتما بعد از باز کردن فایل اتفاق میافتد.
ترکیب سه فاکتور «فکر»، «نگارش»، و «اجرا» مفهومی به اسم Control Flow یا «جریان کنترلی» را در برنامهنویسی به وجود میآورند که بیان کنندهی مدل اجرایی سیستم است.
در کدهای Synchronous، قضیه Control Flow ترتیبی به و شکلی قابل پیشبینی خواهد بود.
از همین رو، کدهای Synchronous کدهایی هستند که طبیعتی ترتیبی دارند. چیزی که در زبان انگلیسی می تواند با واژهی Sequential بیان شود.
بر عکس چیزی که مردم فکر می کنند، مفهوم Asynchronous مشخصا در قطب مخالف Synchronous نیست! بلکه به نوعی مکمل آن است.
کدهای Asynchronous کدهایی هستند که در آنها «ترتیب اجرای» فرامین، دقیقا با «ترتیب نگارش» آنها مطابق نخواهد بود.
این ناهماهنگی چیز بدی نیست:
names.txt
ممکن است ۱ میلی ثانیه طول بکشد، یا ممکن است ۱۰ ثانیه طول بکشد!چون کدهای Asynchronous ذاتی غیر ترتیبی دارند، از جریان اجرایی پیشفرض کدها که به حالت ترتیبی اتفاق میافتد پیروی نمیکنند؛ در حقیقت، هنگام استفاده از مدل Asynchronous، هر بخش از کد می تواند دارای جریان اجرایی جداگانهای باشد. به همین دلیل می توان به کمک اعمال Asynchronous به جای یک جریان اجرایی، چندین و چند جریان اجرایی داشت.
حالا میرسیم به قسمتی که در بیشتر نوشتهها باعث ریختن قیمهها در ماستها میشود! قسمتی که نویسنده مطلب تصمیم میگیرد مفهوم Asynchronous را با مدل پیادهسازی آن در زبانهای مختلف قاطی کند، در حالی که Asynchronous یک مفهوم مستقل است که می توانند در هر سیستم به نوع متفاوتی ظاهر شود. اما چیزی که مهم است، غیر ترتیبی بودن کدهاست که در تمام پیاده سازی ها مشترک است.
نحوهی اجرا شدن کدهای Asynchronous ممکن است به طور موازی اتفاق بیفتند؛ که باعث اجرای Parallel خواهد شد. همچنین ممکن است به طور غیر موازی اتفاق بیفتد که باعث اجرای «همروند» یا Concurrent میشود.
زبانهای مختلف، برای پیاده سازی مدل Asynchronous از راهحلهای متفاوتی استفاده میکنند. در نهایت، موضوع به این برمیگردد که چگونه جریانهای غیرترتیبی در مدل Asynchronous را اجرا و مدیریت می کنند:
هر کدام از روشهای بالا مزایا و معایب خود را دارند. زبانهایی که به «همروند» بودن شهرت دارند، زبانهایی هستند که از تمام این مدلهای استفاده کرده اند و سعی کردهاند به طور مناسبی هر مدل را در سناریو ای که برایش مناسب تر است استفاده کنند.
فرقی ندارد که از کدام زبان استفاده میکنید، و آن زبان از کدام مدل برای پیاده سازی مفهوم Asynchronous استفاده کرده است. در هر حال، هنگام کار با کدهای Asynchronous باید نکات زیر را بخاطر داشته باشید:
بنابراین:
در نوشتهای که خواندید، سعی شد بدون پرداختن و درگیر شدن با جزییات زبانهای مختلف برنامهنویسی و ابزارهایشان، توضیحی ساده از مفاهیم Synchronous و Asynchronous ارائه شود. همچنین از روی عمد، از واژههایی مانند blocking و Non-blocking استفاده نشد تا باعث گمراهی بیشتر نشود؛ چرا که این مفاهیم داستان خودشان را دارند.
امیدوارم این نوشته هم برای خودتان مفید واقع شده باشد، و هم اینکه بتواند رفرنس خوبی برایتان باشد تا برنامهنویس های دیگری که قصد آشنایی با این مفاهیم دارند را به آن ارجاع دهید.