PDA

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



Vahid_Nasiri
پنج شنبه 20 آذر 1382, 00:16 صبح
مثال پنجم :


using System.Threading;

public class yyy
{
public void abc()
{
for ( int i = 0; i<=3;i++)
{
Thread t2 = Thread.CurrentThread;
System.Console.Write(i + "." + t2.Name + " ");
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.abc));
t.Name="One";
t1.Name="Two";
t.Start();
t1.Start();
}
}

Output
0.One 0.Two 1.One 1.Two 2.One 2.Two 3.One 3.Two


در کد فوق به delegate ، نام abc داده شده است. علاوه بر این ، از خاصیت Name کلاس Thread برای دادن نامی منحصر بفرد و متمایز به هر ترد استفاده گردیده است (برای مثال one و two) . تحت شرایط معمول نامهای اطلاق شده به تردها توسط سیستم تعیین می گردد. در اینجا هر دو ترد ، تابعی مشابه به نام abc را اجرا می کنند. اکنون چگونه می توان تشخیص داد که کدام ترد در حال اجرای abc است؟
کلاس ترد می تواند دارای اعضایی به صورت استاتیک و یا instance ( نمونه ، وهله ) باشد. CurrentThread خاصیتی است استاتیک و فقط خواندنی که شیء ترد را بر می گرداند و بیانگر تردی است که هم اکنون یک تابع را فراخوانده است.
در کد فوق ترد t2‌ بیانگر t و یا t1 خواهد بود و خاصیت Name ، نام ترد در حال اجرا را بر می گرداند.



مثال ششم :


using System.Threading;
public class zzz : Thread
{
}

Compiler Error
a.cs(2,14): error CS0509: 'zzz' : cannot inherit from sealed class 'System.Threading.Thread'

کلاس Thread ، کلاسی Sealed می باشد. بنابراین ما نمی توانیم از آن ارث ببریم. طراحان کلاس Thread در مایکروسافت نظرات خاصی پیرامون این کلاس دارند و آنها بر این باورند که تمام موارد لازم را در این کلاس پیش بینی کرده اند بنابراین هیچگونه ابزاری را برای override (تحریف) کردن یا اصلاح آن پیش بینی نکرده اند. پس از این کلاس همانگونه که هست می توان استفاده نمود. لازم به ذکر است که کلاس Thread از اینترفیسی به نام ISerializable مشتق شده است.



مثال هفتم :


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));
System.Console.WriteLine(t.IsAlive);
t.Start();
System.Console.WriteLine(t.IsAlive);
t.Abort();
System.Console.WriteLine(t.IsAlive);
}
}


Output
False
True
Hi
False

کلاس ترد دارای خاصیتی است به نام IsActive که وضعیت ترد جاری را بر می گرداند. هنگامیکه یک شیء Thread ایجاد می شود در وضعیت مرگ (dead) قرار دارد بنابراین این خاصیت مقدار false را بر می گرداند. آغاز کار ترد با اجرای تابع abc خواهد بود بنابراین در این حالت وضعیت true می گردد. هنگامیکه یک ترد Stop و یا Abort می گردد مقدار false می شود.



مثال هشتم :


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();
while ( !t.IsAlive )
System.Console.WriteLine("hi1");
}
}

Output
Hi

کامپیوترهای امروزی بسیار سریع هستند. هنگامیکه ()t.Start فراخوانی می گردد ، حیات یک ترد در کسری از ثانیه شروع می شود. بنابراین حلقه ی while‌ فوق اجرا نخواهد شد ، زیرا شرایط آن به طور آنی false می شود. با کامپیوتری آهسته تر ، قبل از اینکه حیات این ترد آغاز گردد ، ممکن است حلقه ی while برای بارهای کمی اجرا گردد. بنابراین خروجی و سرعت اجرا بسته به سرعت کامپیوتر ممکن است متفاوت باشد. هر زمان که برنامه یک ترد را ایجاد کند ، حاوی این حلقه ی while خواهد بود.



مثال نهم :


using System.Threading;

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

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

Output
Over
Hi 0 Hi 1 Hi 2 Hi 3

فایل اجرایی برنامه ، در ترد خودش اجرا می گردد. بنابراین قبل از فراخوانی تابع Start ، یک ترد در حال اجرا است. پس از اجرای تابع Start ، دو ترد یاد شده همزمان و مستقل از یکدیگر شروع به اجرا می کنند. اولین ترد ، آخرین تابع یعنی writeLine را اجرا کرده و دومین ترد تابع abc را فراخوانی می نماید. اگر بر روی کامپیوتر شما ، time slice مربوط به اولین ترد به پایان برسد ، ممکن است تابع abc‌ قبل از دیگری اجرا گردد. باید تاکید کرد که در حالت تردها هیچگونه گارانتی وجود ندارد که چه زمانی time slice یک ترد پایان خواهد پذیرفت. حتی سیستم عامل نیز در این زمینه به اندازه ی کافی بافراست نیست که گارانتی لازم را ارائه بدهد.



مثال دهم :


using System.Threading;

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

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

Output
Hi 0 Hi 1 Hi 2 Hi 3 Over

در کد فوق تابع Join عامل وقفه است. در این حالت تابع ذکر شده سبب می شود تا برنامه تا زمان پایان پذیرفتن ترد صبر نماید. هرکدی پس از تابع Join تنها پس از خاتمه ی ترد اجرا خواهد شد. بنابراین اگر می خواهیم تا پایان پذیرفتن یک ترد صبر نماییم نیاز به استفاده از تابع Join خواهد بود. Join همانند میزبانی است که آخرین نفر ترک کننده ی میهمانی می باشد.

SSP_Software_team
پنج شنبه 20 آذر 1382, 07:49 صبح
ممنون یکی از یکی بهتر دستت درست :wink:

kablayi
جمعه 23 بهمن 1383, 06:20 صبح
:موفق:

kablayi
جمعه 23 بهمن 1383, 06:35 صبح
:تشویق: :موفق:

bahman.net
جمعه 08 اردیبهشت 1385, 01:58 صبح
ممنون عالیه