PDA

View Full Version : Threads, Events & Mutexes در سی شارپ ، قسمت اول



Vahid_Nasiri
سه شنبه 18 آذر 1382, 23:19 عصر
مقدمه :

Thread ها ( که از این پس به آنها ترد می گوییم ) بر این فرض عمل می کنند که کامپیوتر نسبت به انسانها در اجرای اعمال بغایت سریعتر عمل می نماید و در نتیجه دارای زمان پردازشی بی بار (idle) زیادی بوده و در این بین منتظر عکس العمل و کار از طرف انسانها می شود . تردها وسایلی هستند برای غلبه کردن بر این زمان تلف شده ی پردازشی. آنها چندین عمل را در یک کامپیوتر به سرعت انجام داده و این وهم را ایجاد می نمایند که اعمال همزمان اجرا می گردند. هیچ برنامه ای نمی تواند بدون بکارگیری تردها جامع باشد. قبل از اینکه وارد جزئیات بیشتر تردها از لحاظ برنامه نویسی شویم ، بهتر است چند مثال را با هم مرور نماییم.


مثال یک :


using System.Threading;

public class yyy

{
public static void abc()
{
System.Console.WriteLine("Hi");
}
}

public class zzz
{
public static void Main()
{
ThreadStart ts = new ThreadStart(yyy.abc);
Thread t = new Thread(ts);
System.Console.WriteLine("Before Start");
t.Start();
}
}


Output
Before Start
Hi

در مثال فوق تابع abc در ترد فراخوانی شده و یک Hi را نمایش می دهد. در تابع Main ، شیء ts ایجاد گشته است که نمونه ای از کلاس ThreadStart می باشد و از delegate به ارث رسیده است. بنابراین هر چند ThreadStart یک کلاس است اما خواص یک delegate را نیز دارا می باشد . در اینجا سازنده ی آن تابع abc است. تابع abc در کلاس عمومی yyy تعریف شده است بنابراین توسط سایر کلاس ها نیز قابل استفاده خواهد بود. در ترد تابع به روشی اجرا می شود که دقیقا مشابه فراخوانی آن به صورت مستقیم از کلاس zzz می باشد.
سپس شیء دیگر t ایجاد گردیده است که نمونه ایی از Thread می باشد. سازنده ی این شیء ، همان شیء ts است که توسط ThreadStart ایجاد گردید. به صورت غیرمستقیم ، ts بیانگر تابع استاتیک yyy.abc است زیرا یک delegate می باشد.
تا هنگامیکه از تابع Start استفاده نشود ، تابع yyy.abc فراخوانی نمی گردد و همانطور که در کد فوق ملاحظه گردید کلاس های مربوط به بحث Threading در فضای نام System.Threading قرار گرفته اند.



مثال 2 :


using System.Threading;

public class yyy
{
public void abc()
{
System.Console.WriteLine("Hi");
}
}

public class zzz
{
public static void Main()
{
yyy a = new yyy();
Thread t = new Thread(new ThreadStart(a.abc));
t.Start();
}
}

Output
Hi

مثال فوق شبیه برنامه ی قبلی است و در آن تابع abc فراخوانی شده ، استاتیک نیست. بنابراین باید یک ریفرنس به آن از طرف شیء ساخته شود. شیء delegate مربوط به ThreadStart ، مستقیما بعنوان پارامتر ، به سازنده ی کلاس Thread فرستاده می شود.



مثال سوم :


using System.Threading;

public class yyy
{
public void abc()
{
for ( int i = 0; i<=3;i++)
{
System.Console.Write(i + " ");
}
}

public void pqr()
{
for ( int i = 0; i<=3;i++)
{
System.Console.Write(i+ "...");
}
}
}

public class zzz
{
public static void Main()
{
yyy a = new yyy();
Thread t = new Thread(new ThreadStart(a.abc));
Thread t1 = new Thread(new ThreadStart(a.pqr));
t.Start();
t1.Start();
}
}

Output
0 1 2 3 0...1...2...3...

در مثال فوق دو شیء t و t1 ایجاد و به سازنده های آنها delegate های مختلفی با نامهای مختلف فرستاد شده است (در اینجا abc‌ و pqr به ترتیب). در ادامه نیاز به فراخوانی تابع Start این دو شیء وجود خواهد داشت.



مثال چهارم :


using System.Threading;

public class yyy
{
public void abc()
{
for ( int i = 0; i<=3;i++)
{
System.Console.Write(i + " ");
Thread.Sleep(1);
}
}

public void pqr()
{
for ( int i = 0; i<=3;i++)
{
System.Console.Write(i+ "...");
Thread.Sleep(1);
}
}
}

public class zzz
{
public static void Main()
{
yyy a = new yyy();
Thread t = new Thread(new ThreadStart(a.abc));
Thread t1 = new Thread(new ThreadStart(a.pqr));
t.Start();
t1.Start();
}
}

Output
0 0...1 1...2 2...3 3...

با اضافه کردن تابع Sleep که تابعی استاتیک از کلاس Thread می باشد ، توابع abc و pqr به صورت همزمان فراخوانی می شوند ، اگرچه نه به صورت پشت سرهم و متوالی. این مورد بیانگر مفهوم Threads می باشد. برای مثال کامپیوتر چندین کار را در یک زمان با هم انجام می دهد که به آن Multi-tasking هم گفته می شود.
برای نمونه در MS-Word هنگامیکه حجم یک فایل زیاد باشد می توانید در حالیکه مشغول به تایپ هستید ، کارتان را هم ذخیره نمایید (هر چند کار ذخیره سازی ممکن است کمی طول بکشد) .
هر برنامه ی تحت ویندوز در Thread مخصوص به خودش اجرا می شود. بنابراین اگر دو برنامه اجرا گردند ، دو ترد در حال اجرا خواهند بود. اگر دو ترد همزمان وجود داشته باشد ، در هر دقیقه ، زمان پردازش مهیای 30 ثانیه ای به هرکدام تخصیص داده خواهد شد. اگر سومین برنامه هم اکنون اجرا شود ، ترد جدیدی ایجاد گشته و هر کدام از این سه ترد ، تنها 20 ثانیه از زمان پروسسور را در هر دقیقه به خود تخصیص می دهند.
اگر بجای اجرای برنامه ی سوم ، برنامه ی دوم خودش به تنهایی یک ترد را ایجاد نماید چه اتفاقی خواهد افتاد؟ همانند قبل ، این مورد سبب ایجاد ترد سومی خواهد شد و هر ترد ، 20 ثانیه را به خود اختصاص می دهد. در این حالت برنامه ی اول 20 ثانیه از زمان را به خودش اختصاص داده و برنامه ی دوم 40 ثانیه از زمان پروسسور را به خودش اختصاص خواهد داد. بنابراین تعداد زیاد تردهایی که یک برنامه ایجاد می کند زمان بیشتری از پروسسور را درخواست خواهند کرد.
کامپیوتر زمان مشخصی را به هر ترد اختصاص داده و سپس آنرا به حالت Sleep در خواهد آورد. پس از آن ، تردهای دیگر را اجرا می نماید. به زمانی که به هر ترد داده می شود تا کد خودش را اجرا نماید ، Time slice گفته می شود. اختصاص این تکه های زمانی به سرعت رخ داده و این توهم را پیش می آورد که هیچگونه تقسیمی صورت نگرفته و تمام زمان به یک ترد اختصاص داده شده است.
تابع استاتیک Sleep در کلاس Thread این پروسه را تسهیل می کند. این تابع سبب می شود تا یک ترد برای تعداد مشخصی میلی ثانیه که در پارامتر آن مشخص می شود به حالت Sleep برود. در مثال فوق این زمان یک میلی ثانیه است. در مثال قبلی در یک تکه ی زمانی ، ترد کل تابع را اجرا و کارش را به پایان می رساند اما در این حالت تابع Sleep سبب ایجاد وقفه ای به اندازه ی کافی می شود تا Thread بعدی اجرا گردد. بنابراین کد موجود در توابع یکی پس از دیگری فراخوانی خواهند شد..




مرجع :
فصل اول کتاب C# Classes-Threads,WinForms and XML نوشته ی Vijay Mukhi, Vinay Kalantri , Sonal Mukhi از انتشارات BPB .

SSP_Software_team
چهارشنبه 19 آذر 1382, 07:08 صبح
استاد دستت درست خیلی آقایی :wink: :wink: :wink:

برنامه نویس جوان
چهارشنبه 19 آذر 1382, 15:03 عصر
خیلی ممنون ادامه دهید

AmirZ
سه شنبه 24 شهریور 1383, 13:47 عصر
سلام
ممنونم . اطلاعات مفیدی بود . حتما ادامه دهید.

bahman.net
پنج شنبه 04 خرداد 1385, 01:10 صبح
خیلی خوب بود استاد دستتون درد نکنه

aidinwashere
دوشنبه 09 مرداد 1385, 10:05 صبح
با تشکر از استاد نصیری
میشه ربط این موارد رو با سمافور ها رو هم بفرمایید؟
باور بفرمایید خیلی مطلب خوندم ولی چیزی دستگیرم نشد.

rozalin
جمعه 29 آبان 1388, 14:57 عصر
ممنون
مطلب مفیدی بود

mohammadali68
یک شنبه 25 دی 1390, 00:22 صبح
با سلام اگر ممکنه نحوه ساخت رویداد در سی شارپ را برام توضیح بدید
با تشکر فراوان :لبخندساده: