درخواست های ارتباط
جستجو تنظیمات
لیست دوستان من

برنامه نویسی Parallel در سی شارپ :: مقدمه ای بر Task Parallel Library و کلاس Parallel در دات نت

0 نظرات

پیش از این ما در سری مطالب مرتبط با بحث کار با Thread با نحوه ایجاد و مدیریت Thread ها در دات نت آشنا شدیم. از نسخه 4 دات نت قابلیتی اضافه شد با نام Task Parallel Programming یا TPL که روش جدیدی برای نوشتن برنامه Multi-Theaded است. این قابلیت بوسیله یکسری از کلاس ها که در فضای نام System.Threading.Tasks قرار دارد فراهم شده و به ما این اجازه را می دهد که بدون درگیر شدن مستقیم با Thread ها و Thread Pool ها برنامه های Multi-Threaded بنوسیم. دقت کنید که زمان استفاده از قابلیت TPL دیگر نیازی به استفاده از کلاس های فضای نام System.Threading نمی باشد و به صورت پشت زمینه عملیات ساخت و مدیریت Thread ها برای ما انجام می شود. با این کار شیوه کار با Threadه ا بسیار ساده شده و یکسری از پیچیدگی ها در این بین حذف می شود.


فضای نام System.Threading.Tasks


همانطور که گفتیم TPL در حقیقت مجموعه ای از کلاس ها است که در فضای نام System.Threading.Tasks قرار گرفته. یکی از قابلیت های TPL این است که کارهای محوله را به صورت خودکار بین CPU های سیستم (در صورت وجود) توزیع می کند که این کار در پشت زمینه بوسیله CLR Thread Pool انجام می شود. کارهای انجام شده توسط TPL در پشت زمینه عبارتند از تقسیم بندی وظایف، زمانبندی Thread ها، مدیریت وضعیت (State Management) و یکسری از کارهای اصطلاحاً Low-Level دیگر. نتیجه این کار برای شما بالا رفتن کارآیی برنامه ها بوده بدون اینکه درگیر پیچیدگی های کار با Thread ها شوید. همانطور که گفتیم فضای نام System.Threading.Tasks شامل یکسری کلاس ها مانند کلاس Parallel، کلاس Task و ... می باشد که در ادامه با این کلاس ها بیشتر آشنا می شویم.


نقش کلاس Parallel


یکی از کلاس های TPL که نقش کلیدی را در نوشتن کدهای Parallel ایفا می کند، کلاس Parallel است، این کلاس یکسری متدها در اختیار ما قرار می دهد که بتوانیم بر روی آیتم های یک مجموعه (علی الخصوص مجموعه هایی که اینترفیس IEnumerable را پیاده سازی کرده اند) به صورت parallel عملیات هایی را انجام دهیم. متدهای این کلاس عبارتند از متد های For و ForEach که البته Overload های متفاوتی برای این متدها وجود دارد. بوسیله این متدها می توان کدهایی نوشتن که عملیات مورد نظر را به صورت parallel بر روی آیتم های یک مجموعه انجام دهند. دقت کنید کدهایی که برای این متدها نوشته می شوند در حقیقت همان کدهایی هستند که معمولاً در حلقه های for و foreach استفاده می شوند، با این تفاوت که به صورت parallel اجرا شده و اجرا و مدیریت کدها بوسیله thread ها و CLR Thread Pool انجام شده و البته بحث همزمانی نیز به صورت خودکار مدیریت می شود.

در ابتدا به سراغ متد ForEach می رویم، این متد یک مجموعه که ایترفیس IEnumerable را پیاده سازی کرده به عنوان پارامتر اول و متدی که باید بر روی هر یک اعضای این مجموعه انجام شود را به عنوان پارامتر دوم قبول می کند:

var numbers = new List<int> {2, 6, 8, 1, 3, 9, 6, 10, 5, 4};
Parallel.ForEach(numbers, number =>
{
    Console.WriteLine(number);
    Console.WriteLine("Thread Id: {0}",System.Threading.Thread.CurrentThread.ManagedThreadId);
});

در کد بالا یک آرایه از لیست از نوع int تعریف کرده و در مرحله بعد بوسیله متد ForEach در کلاس Parallel اعضای لیست را پردازش می کنیم، با هر بار اجرا خروجی های متفاوتی دریافت خواهیم کرد:

8
5
Thread Id: 6
4
2
Thread Id: 1
6
3
Thread Id: 5
9
Thread Id: 5
10
Thread Id: 5
1
Thread Id: 5
Thread Id: 4
Thread Id: 6
6
Thread Id: 1
Thread Id: 3

همانطور که مشاهده می کنید شناسه های مربوط به thread در هر بار اجرای کدی مشخص شده در متد ForEach با یکدگیر متفاوت است، دلیل این موضوع ایجاد و مدیریت Thread ها توسط CLR Thread Pool است که ممکن است با هر بار فراخوانی متد مشخص شده به عنوان پارامتر دوم یک thread جدید ایجاد شده یا عملیات در یک thread موجود انجام شود. اما علاوه بر متد ForEach متد For نیست را می توان برای پردازش یک مجموعه استفاده کرد. در ساده ترین حالت این متد یک عدد به عنوان اندیس شروع حلقه، عدد دوم به عنوان اندیس پایان حلقه و یک پارامتر که متدی با پارامتر ورودی از نوع int یا long که نشان دهنده اندیس جاری است قبول می کند، برای مثال در متد زیر بوسیله متد For لیست numbers را در خروجی چاپ می کنیم، اما نه همه خانه های آن را:

var numbers = new List<int> {2, 6, 8, 1, 3, 9, 6, 10, 5, 4};
Parallel.For(3, 6, index =>
{
    Console.WriteLine(numbers[index]);
    Console.WriteLine("Thread Id: {0}", System.Threading.Thread.CurrentThread.ManagedThreadId);
});

با اجرای کد بالا خروجی زیر نمایش داده می شود، البته با هر بار اجرا ممکن است خروجی ها با هم متفاوت باشند:

1
Thread Id: 1
9
3
Thread Id: 3
Thread Id: 4

یکی از کاربردی ترین موارد برای استفاده از کلاس Parallel و متدهای For و ForEach زمانی است که قصد داریم مجموعه حجیمی از اطلاعات را پردازش کنیم و البته پردازش هر المان وابسته به سایر المان ها نیست، زیرا عملیات پردازش المان ها به دلیل اینکه در Thread های مختلف انجام می شوند، ترتیبی در زمان اجرای المان ها در نظر گرفته نشده و ممکن است آیتمی در وسط لیست قبل از آیتم ابتدای لیست پردازش شود. برای مثال، فرض کنید قصد دارید لیستی از تصاویر را گرفته و بر روی آن ها پردازشی انجام دهید یا لیستی از فایل ها را می خواهیم پردازش کنید، در اینجور مواقع به راحتی می توان از کلاس Parallel و متدهای آن استفاده کرد. یکی از مزیت های استفاده از کلاس Task این است که علاوه بر توزیع انجام کارها در میان Thread ها، در صورت موجود بودن بیش از یک CPU در سیستم شما، از سایر CPU ها هم برای پردازش اطلاعات استفاده می کند. در قسمت بعدی در مورد کلاس Task صحبت خواهیم کرد.

نویسنده: حسین احمدی

منبع: ITPRO

آیا این مطلب را پسندیدید؟
ردیف عنوان قیمت
1 کار با Thread ها در زبان سی شارپ :: آشنایی با Process ها، Thread ها و AppDomain ها رایگان
2 کار با Thread ها در زبان سی شارپ :: آشنایی با ماهیت Asynchronous در Delegate ها رایگان
3 کار با Thread ها در زبان سی شارپ :: آشنایی با فضای نام System.Threading و کلاس Thread رایگان
4 کار با Thread ها در زبان سی شارپ :: آشنایی با Thread های Foreground و Background در دات نت رایگان
5 کار با Thread ها در زبان سی شارپ :: آشنایی با مشکل Concurrency در برنامه های Multi-Threaded و راهکار های رفع این مشکل رایگان
6 کار با Thread ها در زبان سی شارپ :: آشنایی با کلاس Timer رایگان
7 کار با Thread ها در زبان سی شارپ :: آشنایی با CLR ThreadPool در دات نت رایگان
8 برنامه نویسی Parallel در سی شارپ :: مقدمه ای بر Task Parallel Library و کلاس Parallel در دات نت رایگان
9 برنامه نویسی Parallel در سی شارپ :: آشنایی با کلاس Task در سی شارپ رایگان
10 برنامه نویسی Parallel در سی شارپ :: متوقف کردن Task ها در سی شارپ - کلاس CancellationToken رایگان
11 برنامه نویسی Parallel در سی شارپ :: کوئری های Parallel در LINQ رایگان
12 آشنایی با کلمات کلیدی async و await در زبان سی شارپ رایگان
13 استفاده از متد WhenAll برای اجرای چندین Task به صورت همزمان در سی شارپ رایگان
هیچ نظری ارسال نشده است

برای ارسال نظر ابتدا به سایت وارد شوید

arrow