CSCIENCE

CSCIENCE

۴ مطلب در اسفند ۱۳۹۲ ثبت شده است

آشنایی با Task



قبل از اینکه Async در سیشارپ 5 پدیدار شود، دات نت در فریم‌ورک 4، موجودی(!) به نام Task را معرفی کرد که زیرساخت اصلی Async در سیشارپ 5 است. Task برای راحت‌تر کردن و مدیریت بهتر ناهمگامی بوجود آمده است و امکانات فراوانی را در این زمینه در اختیار برنامه نویس قرار می‌دهد. اگر بخواهیم به‌طور خلاصه شئ Task را تعریف کنیم، می‌توان گفت Task یک عمل در حال اجرا را در خود کپسوله می‌کند و از طریق آن می‌توانیم از وضعیت آن عمل باخبر شویم و یا آن را کنترل کنیم. البته این تعریف خیلی تعریف ساده ایست اما برای شروع مناسب است. در ادامه بیشتر با این موجود آشنا خواهید شد.
هنگامی که شما می‌خواهید یک سری عملیات را به صورت ناهمگام اجرا کنید، کافیست نمونه‌ای از Task ایجاد کنید و مدیریت اجرای آن را به او بسپارید. به محض اینکه عملیات را به Task نسبت می‌دهید، Task یک Thread آزاد را از Thread Pool انتخاب می‌کند و عملیات شما را در آن Thread اجرا می‌کند. ممکن است بپرسید Thread Pool چیست؟
به طور خلاصه می‌توان گفت که دات‌نت برای جلوگیری از هزینه‌های ایجاد و حذف Threadها، مجموعه‌ای از Threadهای آماده به کار را فراهم کرده است و برنامه‌ی شما در صورت نیاز به Thread، می‌تواند از این Threadها استفاده کند. هر Thread بعد از اتمام کار، دوباره به مجموعه باز می‌گردد (برای دریافت کار بعدی).
بنابراین Task به طور اتوماتیک یک Thread از مجموعه انتخاب می‌کند و با آن کار می‌کند و پس از اتمام کار، آن را به مجموعه باز می‌گرداند. اکنون با داشتن یکسری اطلاعات کلی در مورد Task، ادامه‌ی آموزش را با مثال‌های طبقه بندی شده بر اساس نوع عملیات پیش خواهم برد و نکات تکمیلی را اضافه خواهم کرد.

نوع اول) Fire and Go
در این نوع از عملیات، نتیجه‌ی عملیات مهم نیست، فقط قرار است انجام شود و مهم نیست که کی و به چه شکل پایان می‌یابد. از اینجا به بعد یک تابع را به عنوان واحد عملیاتی در نظر خواهیم گرفت و به جای کلمه‌ی عملیات از تابع استفاده می‌کنیم.
فرض کنید تابعی به شکل زیر دارید که قرار است عملیاتی طولانی انجام دهد:

public void DoJob(){
     // Function Body
}

اگر بخواهیم تابع بالا را به روش Fire and Go و به صورت موازی اجرا کنیم، کافیست دستور زیر را اجرا کنیم:

Task.Run(()=>DoJob());

در حالتی هم که تابع مورد نظر، آرگومان ورودی داشته باشد، تنها کافیست هنگام فراخوانی با Task.Run، آرگومان‌ها را در آن بنویسید. به همین سادگی!
در بخش‌های بعدی با انواع مختلف مثال‌ها و ابزارهای مدیریت Task بیشتر آشنا خواهید شد.
۱ موافقین ۰ مخالفین ۰ ۲۵ اسفند ۹۲ ، ۲۱:۵۴
cscience

دلایل استفاده ناهمگامی (Asynchrony)



هنگامی که یکسری عملیات به ترتیب و پشت‌سر هم انجام شوند، به عبارتی، هنگامی که هر عمل بعد از پایان عمل قبلی اجرا شود، می‌گوییم روند اجرای آن‌ها همگام یا Synchronous است. حال اگر شرایط را فراهم کنیم که عملیات مختلف بتوانند بدون انتظار برای پایان دیگر عملیات، شروع به کار کنند (موازی یا همروند)، روند اجرای آن‌ها را ناهمگام یا Asynchronous گوییم. البته این تعریف دقیق نیست و تنها برای ایجاد تصویری مناسب از Asynchrony نوشته شده است. در ادامه به طور خلاصه به چندتا از فواید ناهمگامی اشاره می‌کنم.

1. رابط کاربری (UI)
معروف‌ترین ابزارهای ایجاد رابط‌های کاربری در سیشارپ، Windows Form و WPF هستند. در هر دو تکنولوژی، برای مدیریت رابط کاربری (نمایش اجزا، رخدادها و ...) تنها از یک Thread* استفاده می‌شود. اکنون فرض کنید برنامه‌ی شما قرار است به عنوان مثال بعد از کلیک بر روی یک دکمه، عملیاتی طولانی را شروع کند (محاسبات پیچیده، درخواست‌های تحت شبکه، ورودی/خروجی دیسک و ...). با توجه به اینکه در خواست اجرا از طریق رابط کاربری بوده است و در آن‌جا تنها یک Thread وجود دارد، این عملیات، مدت زمان طولانی Thread مخصوص رابط کاربری را Block می‌کنند و در نتیجه رابط کاربری تا پایان عملیات، توانایی پاسخ‌گویی به کاربر را نخواهد داشت. درست است که عملیات مورد نظر در حال انجام است اما کاربر هیچگاه رابط کاربری از کار افتاده یا Unresponsive را نمی‌پسندد. بهتر است عملیات طولانی در Thread دیگر، موازی با رابط کاربری اجرا شود تا رابط کاربری همواره پاسخ‌گوی کاربر باشد و به نحوی میزان پیشرفت عملیات طولانی را نیز نمایش دهد.

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

3. استفاده از حداکثر توان پردازشی
سخت‌افزارهایی که امروزه راهی بازار می‌شوند، بسیار قدرتمندتر از آنی هستند که ما (با برنامه‌های معمولی البته) از آن‌ها استفاده می‌کنیم. قلب کامپیوتر یعنی CPU هم از این قضیه مستثنا نیست. CPUهای فعلی حداقل 2 هسته‌ی پردازشی دارند. هسته‌ها می‌توانند قابلیت پردازش موازی و افزایش سرعت برنامه را فراهم کنند. در صورتی که برنامه‌ی شما موازی نباشد، شما تنها از یک هسته CPU استفاده می‌کنید (برای امتحان کافیست برنامه‌ای بنویسید که یک حلقه‌ی طولانی داشته باشد، آن را اجرا کنید و سپس از طریق Task Manager، میزان استفاده از CPU را چک کنید). قابلیت Async در سیشارپ امکان استفاده از همه‌ی هسته‌های پردازشی را به شما می‌دهد.


*مبحث Threadها در این سری آموزشی باز نخواهد شد. برای درک بهتر مفاهیم آموزشی، پیشنهاد می‌کنم از منابع دیگر در مورد Threadها مطالعه کنید.
۱ موافقین ۰ مخالفین ۰ ۲۴ اسفند ۹۲ ، ۱۸:۱۶
cscience

برنامه نویسی Asynchronous به شما اجازه می‌دهد تا بتوانید اعمال مختلف را به صورت همزمان در برنامه‌ی خود پیش ببرید. به عبارت دیگر، این قابلیت از Block شدن برنامه شما، در شرایطی که برنامه در حال انجام کاری طولانی مدت است، جلوگیری می‌کند و باعث می‌شود برنامه‌ Responsive باقی بماند. از دیگر فواید برنامه Asynchronous، می‌توان به استفاده از حداکثر توان سیستم اشاره کرد. امروزه اکثر پردازنده‌ها، چندین هسته‌ی پردازشی دارند که یک برنامه‌ی غیر موازی نهایتا از یک هسته‌ی پردازنده استفاده می‌کند اما با نوشتن یک برنامه‌ی Asynchronous و ایجاد یک الگوی موازی سازی، محاسبات شما به صورت موازی روی هسته‌های مختلف CPU اجرا می‌شود.

سیشارپ یا بهتره بگم دات نت، قابلیت‌ها و روش‌های مختلفی را برای این کار فراهم کرده‌است. یکی از قابلیت‌هایی که در سیشارپ 5 اضافه شده است، کلمات کلیدی async و await است. شما می‌توانید تنها با استفاده از این 2 کلمه کلیدی، برنامه Asynchronous بنویسید! در پست‌های بعدی آموزش مختصر و کوتاهی درباره این قابلیت جدید ارائه خواهم داد.

۰ موافقین ۰ مخالفین ۰ ۲۱ اسفند ۹۲ ، ۱۱:۴۷
cscience
در مبحث محاسبه پذیری و توابع Primitive Recursive یا به اختصار PR، ثابت میشه که تمامی توابع PR محاسبه پذیرند، در صورتی که برعکس آن برای تمامی توابع صادق نیست. یعنی حداقل یک تابع وجود دارد که محاسبه پذیر است اما PR نیست. یکی از این توابع، تابع Ackermann است. اثبات PR نبودن این تابع را در فایل زیر نوشته‌ام*.

دانلود


* منبع اصلی این اثبات این لینک است که من اثبات‌های تمامی لم‌های آن را در فایل خودم آورده‌ام.
۱ موافقین ۰ مخالفین ۰ ۱۳ اسفند ۹۲ ، ۲۳:۴۹
cscience