PDA

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



Vahid_Nasiri
یک شنبه 30 آذر 1382, 23:06 عصر
مثال بیست و پنجم :


using System.Threading;

public class yyy
{
public void abc()
{
Monitor.Enter(this);
Monitor.Enter(this);
for ( int i = 1; i<=3;i++)
{
System.Console.WriteLine(
i + " " + Thread.CurrentThread.GetHashCode() + " ");
}
Monitor.Exit(this);
}
}

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.Start();
t1.Start();
}
}

Output
1 2
2 2
3 2

در برنامه ی فوق ما دو ترد t و t1 را داریم. فرض کنیم که ترد t ابتدا کارش را آغاز می کند. در این زمان این ترد توسط اولین و دومین Monitor.Enter بدون هیچگونه تاملی شروع به کار می کند. ترد t1 باید برای ورود به اولین Monitor.Enter صبر کند زیرا ترد t ، تابع Enter را دوبار فراخوانی کرده است اما فقط یکبار خارج (Exit) شده است. بنابراین برنامه هرگز خاتمه پیدا نمی کند. اگر تابع Exit دوبار فراخوانی شود ، ترد t1 امکان عمل خواهد یافت.



مثال بیست و ششم :


using System.Threading;

public class yyy
{
public int j=1;
public void abc()
{
Monitor.Enter(j);
for ( int i = 1; i<=3;i++)
{
System.Console.WriteLine(
i + " " + Thread.CurrentThread.GetHashCode() + " ");
}
Monitor.Exit(j);
}
}

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


Output
1 2
2 2
3 2
Unhandled Exception: System.Threading.SynchronizationLockException: Exception of type System.Threading.SynchronizationLockException was thrown.
at yyy.abc()

تابع Monitor.Enter تنها اشیاء را بعنوان پارامتر می پذیرد و نه متغیرها را . اگر متغیری در اینجا بکار گرفته شود یک Exception رخ خواهد داد. بنابراین انواع عددی و یا اشیاء null را نمی توان در اینجا بعنوان پارامتر ورودی مورد استفاده قرار داد.



مثال بیست و هفتم :


using System.Threading;

public class xxx
{

}

public class ttt
{

}

public class yyy
{
static int p = 1;
xxx x = new xxx();
ttt t = new ttt();
public void abc()
{
if ( p == 1)
{
Monitor.Enter(x);
p++;
}
else
Monitor.Enter(t);
for ( int i = 1; i<=3;i++)
{
Thread.Sleep(1000);
System.Console.WriteLine(
i + " " + Thread.CurrentThread.GetHashCode() + " ");
}
Monitor.Exit(x);
}
}

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.Start();
t1.Start();
}
}

Output
1 2
1 3
2 2
2 3
3 2
3 3

از تابع Enter باید با دقت و احتیاط استفاده نمود. در مثال فوق متغیر P در ابتدا دارای مقدار 1 است. اولین ترد یعنی t ، مقدار P را مساوی یک مشاهده می کند. بنابراین عبارت if صحیح خواهد بود. در ادامه از تابع Monitor.Enter با پارامتر x استفاده می شود. این ترد با کمک تابع Sleep به خواب می رود ، در حالیکه ترد دوم (t1) اجرای تابع abc را شروع می کند و در اینجا آن مقدار متغیر P را معادل 2 خواهد دید. در ادامه این ترد با تابع Monitor.Enter با پارامتر t ملاقات خواهد کرد. شیءایی که به این تابع Enter بعنوان پارامتر فرستاده شده است کاملا متفاوت است با شیء t ایی که برای ترد قبلی مورد استفاده قرار گرفت. بنابراین هر دو ترد تابع Enter را اجرا خواهند کرد که سبب از بین رفتن هدف استفاده ی اولیه از تابع Enter است. برای اینکه تابع Enter همانطور که انتظار می رود کار کند باید پارامتر مشابهی را بکار گرفت.

از مفهوم Lock به صورت معمول برای توضیح دادن کلاس Monitor استفاده می شود. هنگامیکه یک ترد Lock می شود سایر تردها باید صبر کنند تا این قفل گشوده شود.




مثال بیست و هشتم:



using System.Threading;

public class yyy
{
public void abc()
{
bool b = Monitor.TryEnter(this);
System.Console.WriteLine(b);
for ( int i = 1; i<=3;i++)
{
Thread.Sleep(1000);
System.Console.WriteLine(
i + " " + Thread.CurrentThread.GetHashCode() + " ");
}
Monitor.Exit(this);
}
}

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.Start();
t1.Start();
}
}


Output
True
False
1 2
1 3
2 2
2 3
3 2
3 3


تابع TryEnter مشابه تابع Enter است اما سبب block شدن نخواهد گردید. اگر ترد به صورت موفقیت آمیزی بتواند enter کند ، این تابع true بر می گرداند. این چیزی است که برای بار اول اتفاق می افتد. اما در زمانی که ترد دوم می خواهد وارد شود ، این تابع false بر می گرداند.




مثال بیست و نهم :‌


using System.Threading;

public class yyy
{
public void abc()
{
bool b = Monitor.TryEnter(this,1000);
System.Console.WriteLine(b);
for ( int i = 1; i<=3;i++)
{
Thread.Sleep(1000);
System.Console.WriteLine(
i + " " + Thread.CurrentThread.GetHashCode() + " ");
}
Monitor.Exit(this);
}
}

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.Start();
t1.Start();
}
}

Output
True
False
1 2
1 3
2 2
2 3
3 2
3 3

تابع TryEnter اعداد را نیز بعنوان پارامتر می پذیرد و این اعداد بیانگر مدت زمانی که TryEnter باید منتظر بماند و یا بلاک کند ، می باشد. در مثال فوق ، timeout از زمانی که ترد t در تابع صرف کرده است ، تجاوز نموده است. بنابراین ما مقدار false را دریافت خواهیم کرد. اگر زمان پارامتر افزایش داده شود ، خروجی true می گردد. اگر مقدار پارامتر نامتناهی شود ، رفتار تابع TryEnter و تابع Enter یکی خواهند گردید.

faramarz_s
جمعه 03 بهمن 1382, 17:53 عصر
جناب نصیری ادامه نمی دهید.؟ :oops:

مهدی فهمیده غلامی
شنبه 02 اسفند 1382, 03:44 صبح
اقای نصیری با تشکر از زحمات بی دریغ شما و همکارانتان
یکی از کاربرد های Thread اجرای موازی فرایند ها می باشد
فرض کنید 4 تا editbox داریم من می خوام به محتوای editbox1 هر 1 میلی ثانیه وبه editbox2 هر 2 میلی ثانیه
editbox3 هر 3 میلی ثانیه و بالاخره editbox4 هر 4 میلی ثانیه افزوده شود این زمان بندی با Thread ها چگونه صورت
می گیرد؟؟ و برنامه اش چگونه پیاده سازی می شود؟؟؟

مهدی فهمیده غلامی
شنبه 02 اسفند 1382, 03:45 صبح
ایا 1 Sleep واقعا دقیق است؟ ومی توان برای کارهای Real Time روش حساب کرد؟ایا زمان پاسخ دقیقی را گارانتی می کنند؟

مهدی فهمیده غلامی
شنبه 02 اسفند 1382, 03:51 صبح
می شه تفاوت forground Thread وBackground Thread را دوباره توضیح دهید چون مثال هفدهم را حتی با تغییر ان اجرا کردم نتیجه یکسان بود؟؟ چه اتفاقی می افته؟

مهدی فهمیده غلامی
شنبه 02 اسفند 1382, 03:53 صبح
می شه بفرمایید که این Thread ها بعنوان نمونه در کد شماره 21 چگونه اجرا می شوند (در زمان اجرا)؟؟؟؟من که با trace کردن برنامه به نحوه اجرای ان پی نبردم.

مهدی فهمیده غلامی
شنبه 02 اسفند 1382, 03:57 صبح
تابع ThreadStart دقیقا چکار می کنه و منظور از اینکه Delegate است یعنی چی ؟ Delegate ها که فقط یه function pointer به
توابع مشابه هست!!!

youngstring
جمعه 06 دی 1387, 16:24 عصر
با سلام و خسته نباشید.مطالبتون خیلی گره گشای مشکلات من بود.من هیچ مرجع فارسی درمورد متدهای مختلف کلاس مانیتور پیدانکردم.اینها متدهای مختلفی هستند که کلاس مانیتور دارد.میخواستم یه نفر لطف کنه و در مورد هر کدوم یه توضیحی برای من بنویسه که چه موقع استفاده می شن. با تشکر
Monitor.Enter Method
Monitor.Exit Method
Monitor.Pulse Method
Monitor.PulseAll Method
Monitor.TryEnter(System.Object) Method
Monitor.TryEnter(System.Object, int) Method
Monitor.TryEnter(System.Object, System.TimeSpan) Method
Monitor.Wait(System.Object, int) Method
Monitor.Wait(System.Object, System.TimeSpan) Method
Monitor.Wait(System.Object) Method

vcldeveloper
جمعه 06 دی 1387, 17:09 عصر
من هیچ مرجع فارسی درمورد متدهای مختلف کلاس مانیتور پیدانکردم.اینها متدهای مختلفی هستند که کلاس مانیتور دارد.میخواستم یه نفر لطف کنه و در مورد هر کدوم یه توضیحی برای من بنویسه که چه موقع استفاده می شن.
اگر با مفهوم Monitor آشنا باشید، کاربرد اون متدها را هم راحت متوجه میشید. پس من توصیه می کنم درباره مفهوم Monitor تحقیق کنید، و آن را با Semaphor مقایسه کنید.

youngstring
یک شنبه 08 دی 1387, 13:46 عصر
سلام.در جواب شما من از مانیتور اینو فهمیده ام که سیستمیه که اجازه نمی ده چند ترد همزمان از یک تکه کد خاص در برنامه استفاده کنند و باعث ایجاد نتایج درهم و برهمی بشند با تعریف فوق چهار متد اول قابل فهم هستند ولی متد های زیر چی هستند و چه موقع استفاده می شند .با تشکر.
Monitor.TryEnter(System.Object) Method
Monitor.TryEnter(System.Object, int) Method
Monitor.TryEnter(System.Object, System.TimeSpan) Method
Monitor.Wait(System.Object, int) Method
Monitor.Wait(System.Object, System.TimeSpan) Method
Monitor.Wait(System.Object) Method

vcldeveloper
یک شنبه 08 دی 1387, 15:04 عصر
در جواب شما من از مانیتور اینو فهمیده ام که سیستمیه که اجازه نمی ده چند ترد همزمان از یک تکه کد خاص در برنامه استفاده کنند و باعث ایجاد نتایج درهم و برهمی بشند با تعریف فوق چهار متد اول قابل فهم هستند ولی متد های زیر چی هستند و چه موقع استفاده می شند .

http://www-cse.ucsd.edu/classes/fa05/cse120/lectures/120-l6c.pdf
http://igoro.com/archive/overview-of-concurrency-in-net-framework-35/
http://msdn.microsoft.com/en-us/library/hf5de04k.aspx