تقييم الموضوع :
  • 0 أصوات - بمعدل 0
  • 1
  • 2
  • 3
  • 4
  • 5
الدرس الثامن والأربعون - Multithreading
#1
كاتب الموضوع : أحمد جمال

بسم الله الرحمن الرحيم .
السلام عليكم ورحمة الله وبركاته .

تعرف نظم التشغيل الحديثة بأنها multitasking systems وهو ما يعني امكانية تنفيذ اكثر من مهمة في نفس الوقت ، لذا تجد أن بامكانك تشغيل عدة برامج في نفس الوقت .

برامج .net من هذا النوع افتراضياً ، لكنك تلاحظ في بعض البرامج ان البرنامج الواحد قادر على تنفيذ اكثر من عملية في نفس الوقت دون أن يكون لهما تأثير متعارض ، هذا ما يعرف باسم multithreading .

لذا تجد ان برنامج الماسنجر يتيح لك ارسال ملفات والحديث واستخدام الكاميرا والتحدث مع اكثر من شخص بنفس الوقت ، وهو ما لم يكن الماسنجر قادراً عليه لو لم يكن يفصل هذه المهام داخل البرنامج الواحد عن بعضها ، هذا هو مضمون درسنا الحالي .

جميع الأوامر التي سنتعامل معها هنا تقع تحت نطاق الأسماء System.Threading ، لذا قم باستيراده أولاً .

العناصر الاساسية داخل مجال الاسماء هذا هي :

Thread : لتعريف Thread جديد والتعامل معه .
ThreadPool : مجموعة من ال Threads يمكن لها التعامل فيما بينها .
ThreadState : Enum يحتوي على عدة حالات لأي Thread .
ThreadStart : بدء التنفيذ في Thread .
ThreadPriority : تحديد اولوية هذا ال Thread .


بالاضافة إلى :

Semaphore
Mutex
Monitor


وهي في الاساس الجوريزمات تستخدم لعمليات التزامن synchronization بحيث لا يسمح لأكثر من Thread بالوصول إلى نفس المصادر في نفس الوقت ، لمزيد من التعرف على هذه الالجوريزمات يمكن البدء من هنا :
http://en.wikipedia.org/wiki/Semaphore_(programming)
http://en.wikipedia.org/wiki/Mutual_exclusion
http://en.wikipedia.org/wiki/Monitor_(synchronization)

نواصل في الدرس القادم إن شاء الله .
}}}
تم الشكر بواسطة: rabia al hamdani
#2
System.Threading.Thread

الفئة الاساسية في مجال الاسماء هذا ، تتيح لنا انشاء threads وتنفيذ مهامنا المختلفة عليها ، مكونات هذه الفئة الاساسية هي :

Sleep() : توقف عمل ال thread لفترة من الوقت .
IsAlive : قيمة توضح إذا كان ال thread ما زال يعمل ام لا .
IsBackground : إذا كان ال thread يعمل في background .
Priority : الأولوية الحالية .
ThreadState : حالة ال Thread .
Name : اسم ال thread .
Abort() : خروج .
Join() : توقف عمل ال thread حتى حدوث الحدث في join .
Resume() : استئناف العمل بعد ايقافه .
Start() : بدء العمل للمرة الأولى .
Suspend() : ايقاف العمل مؤقتاً .


سنقوم بداية بعمل تجربة سريعة للاستدلال على معنى ان يتم تنفيذ مهمتين في نفس الوقت ، نعود بعدها لاستئناف شرح المفاهيم الخاصة بالموضوع .

قم بتجربة الكود التالي :

c#:

كود :
[FONT=Tahoma]static void Main(string[] args)
{[/FONT]
[FONT=Tahoma]order1();
order2();
[/FONT]
[FONT=Tahoma]Console.ReadKey();
}[/FONT]
[FONT=Tahoma]static void order1()
{
for (int i = 0; i < 100; i++)
{
Console.ForegroundColor = ConsoleColor.Green;
Console.Write(i.ToString() + " ");
}
}[/FONT]
[FONT=Tahoma]static void order2()
{
for (int i = 100; i > 0; i--)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.Write(i.ToString() + " ");
}
}[/FONT]


vb.net:

كود :
[FONT=Tahoma]Private Shared Sub Main(ByVal args As String())

order1()
order2()


Console.ReadKey()
End Sub
Private Shared Sub order1() [/FONT]
[FONT=Tahoma]For i As Integer = 0 To 99
Console.ForegroundColor = ConsoleColor.Green
Console.Write(i.ToString() + " ")
Next
End Sub
Private Shared Sub order2() [/FONT]
[FONT=Tahoma]For i As Integer = 100 To 1 Step -1
Console.ForegroundColor = ConsoleColor.Red
Console.Write(i.ToString() + " ")
Next
End Sub [/FONT]



الكود كما هو واضح يقوم بطباعة الأرقام تصاعدياً وتنازلياً ، الناتج الطبيعي هو طباعة التصاعدي ومن ثم التنازلي ، في حين يتم طباعة نتائج الدالة الأولى بالأخضر والثانية بالأحمر للتفريق لتكون شاشة النتائج بالشكل التالي مثلاً :


وهذا الطبيعي ، يتم تنفيذ الدالة الأولى حتى الانتهاء ومن ثم الثانية حتى الانتهاء ، أما الآن سنقوم بتعريف threads مختلفة للتنفيذ بحيث يتم تنفيذ كل دالة على واحد منها حيث سيتم تنفيذهم على البروسيسور في نفس الوقت ، الكود التالي مثلاً :

c#:

كود :
[FONT=Tahoma]static void Main(string[] args)
{
System.Threading.Thread t1 = new System.Threading.Thread(order1);
t1.Start();[/FONT]
[FONT=Tahoma]System.Threading.Thread t2 = new System.Threading.Thread(order2);
t2.Start();[/FONT]
[FONT=Tahoma]Console.ReadKey();
}[/FONT]
[FONT=Tahoma]static void order1()
{
for (int i = 0; i < 100; i++)
{
Console.ForegroundColor = ConsoleColor.Green;
Console.Write(i.ToString() + " ");
}
}[/FONT]
[FONT=Tahoma]static void order2()
{
for (int i = 100; i > 0; i--)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.Write(i.ToString() + " ");
}
}[/FONT]


vb.net:


كود :
[FONT=Tahoma]Private Shared Sub Main(ByVal args As String())
Dim t1 As New System.Threading.Thread(order1)
t1.Start()

Dim t2 As New System.Threading.Thread(order2)
t2.Start()

Console.ReadKey()
End Sub
Private Shared Sub order1() [/FONT]
[FONT=Tahoma]For i As Integer = 0 To 99
Console.ForegroundColor = ConsoleColor.Green
Console.Write(i.ToString() + " ")
Next
End Sub
Private Shared Sub order2() [/FONT]
[FONT=Tahoma]For i As Integer = 100 To 1 Step -1
Console.ForegroundColor = ConsoleColor.Red
Console.Write(i.ToString() + " ")
Next
End Sub [/FONT]


الآن لنرى طبيعة النتائج .


بالطبع النتائج لن تكون كما هي كل مرة ، جرب تغيير ال Priority مثلاً لواحد منهم وجرب النتائج ، ستجد أن صاحب الأولوية الأعلى يتم الانتهاء منه قبل الثاني ، الكود التالي مثلاً :


كود :
[FONT=Tahoma]t1.Priority = System.Threading.ThreadPriority.Highest;[/FONT]


ستصبح النتائج بالشكل التالي :




ستجد اختلافات في التنفيذ ، لكن الشاهد هو أن الكودين تم تنفيذهم سوية في هذا الوقت .


بالطبع ليس هذا هو استخدام الوحيد لل threads ، ولكنها كانت فقط مقدمة سريعة . سنعود ونواصل .
}}}
تم الشكر بواسطة: rabia al hamdani
#3
كاتب المشاركة : أحمد جمال

قبل ان اواصل ، هذه دروس لشرح معنى Threads للأخ عصام :
http://vb4arb.com/vb/showthread.php?726
http://vb4arb.com/vb/showthread.php?727

للأخ سامر سلو دروس أيضاً ، سنشير إليها حينما نبلغ الجزء الخاص بذلك ضمن الدرس .
}}}
تم الشكر بواسطة:
#4
ال Priority :

تحدد ال Priority أولوية التنفيذ عندما يتم ادخال ال threads على البروسيسور ، حيث ان ال thread ذو الاولوية الأعلى يحظى بعدد مرات تنفيذ ، لتقريب المفهوم نفترض ان لدينا

- مهمة 1 اولوية قصوى .
- مهمة 2 اولوية قصوى .


في هذه الحالة يتم ادخال المهمة 1 للبروسيسور ، ثم 2 ، ثم 1 وهكذا .
أما في حال كون مهمة 2 ذات اولوية اقل ، يكون الأمر بالشكل التالي :
المهمة 1 ، المهمة 1 ، المهمة 1 ، المهمة 2 ، المهمة 1 ، المهمة 1 ، المهمة 1 ، المهمة 2 ... وهكذا حتى الانتهاء من احدهما .

ليس هذا مكان شرح الجوريزمات البروسيسور ، إنما لو أردت الزيادة يمكنك البدء من هنا ، حيث تجد عدة انواع من ال scheduling .
http://en.wikipedia.org/wiki/Scheduling_%28computing%29

نعود مرة أخرى ، لتحديد Priority أي مهمة لدينا نستخدم ال enum التالي :


كود :
public enum ThreadPriority
{
AboveNormal,
BelowNormal,
Highest,
Idle,
Lowest,
Normal, // Default value.
TimeCritical
}
ويصبح الكود بالشكل التالي مثلاً :

كود :
t1.Priority = System.Threading.ThreadPriority.Highest;


قبل البعد عن المواضيع الاساسية ، لا تنسى ان بامكانك استخدام sleep لايقاف التنفيذ لمدة ، supponse لايقاف مؤقت ... الخ من النقاط التي بدأنا بها شرحنا لهذا الدرس .

يتبع ...
}}}
تم الشكر بواسطة:
#5
ParameterizedThreadStart :

لعلك لاحظت في المثال السابق اننا نمرر الدالة ومن ثم نقوم بعمل start لها لتنفيذها في thread منفصل ، لكن ماذا لو كانت هذه الدالة تستقبل بارميترات ؟

الحل بسيط ، باستخدام ParameterizedThreadStart بالشكل التالي مثلاً :

c#:

كود :
Thread t = new Thread(new ParameterizedThreadStart(functionname));
t.Start(parms);

vb.net:

كود :
Dim t As New Thread(New ParameterizedThreadStar(functionname))
t.Start(parms)


}}}
تم الشكر بواسطة:
#6
foreground and background .

هناك نوعان من ال threads :

ForeGround Thread : هذا يعني ان البرنامج لا يمكن ان يغلق حتى يتم الانتهاء من تنفيذ جميع ال foreground threads الموجودة فيه ، النوع الافتراضي لأي thread تقوم بانشاءه هو من هذا النوع .

BackGround Thread : هذا يعني ان البرنامج يمكن ان يتم اغلاقه حتى لو لم يتم تنفيذ كافة ال background threads ، يتم عمله بالشكل التالي مثلاً :

كود :
[FONT=Tahoma]t.IsBackground = true;[/FONT]


الدرس القادم سوف نبدأ في المعاناة رقم 1 مع ال multithreading ، مشكلة التداخل بين المهام وعملية ال Synchronization .
}}}
تم الشكر بواسطة:
#7
كاتب المشاركة : أحمد جمال


بصراحة كنت انوي كتابة موضوع كامل عن ال Threads Synchronization ، ولكني لم اجد نفسي قادراً على اضافة أي جديد في هذا الموضوع لمقال الاخ محمد سامر سلو على هذا الرابط :

http://vb4arb.com/vb/showthread.php?953

لذا يمكنك متابعة الدرس من هناك ، ثم العودة إلى هنا مرة أخرى .

الدرس الذي بعده كان ايضاً عن ال Threadbool ، موجود هنا أيضا للأخ محمد :
http://vb4arb.com/vb/showthread.php?785

الدرس بالفيجوال بيسك.نت ، إذا كنت ترغب في العرض باستخدام c# يمكنك التحويل من هنا .
http://labs.developerfusion.co.uk/convert/csharp-to-vb.aspx

لذا سآخد راحة اليوم ، نلتقي غداً مع BackgroundWorker وبعدها تعقيب للأخ supersmart .



}}}
تم الشكر بواسطة:
#8
BackgroundWorker :

تستخدم ال BackgroundWorker لتنفيذ مهمة معينة تأخذ وقتاً طويلاً بعيداً عن المسار الاساسي للبرنامج ، من أمثلة ذلك الدوال الخاصة بالقراءة من web service أو عمليات معالجة الصور او جلب بعض البيانات من كومبيوتر آخر أو تنفيذ عملية بحث ، او اجراء مجموعة من العمليات طويلة الأمد .

ومع أنك كان بإمكانك عمل هذه الدوال عن طريق تنفيذها في thread تقليدي ، إلا أن BackgroundWorker تعطيك مزيد من التحكم ، ببساطة يمكنك اخباره ال بالدالة التي ترغب في تنفيذها ومن ثم تشغيلها عن طريق RunWorkerAsync() ، أخيراً بعد انتهاء التنفيذ يتم تنفيذ حدث RunWorkerCompleted والتي يمكنك فيه مثلاً عرض النتائج بعد انتهاء تنفيذ هذه المهمة .

للبدء بالعمل قم بعمل Windows Form ، قم برسم بعض الادوات ومن ثم ضع زر امر للبدء بتنفيذ المهمة ، واخيراً قم بسحب أداة BackgroundWorker بالشكل التالي مثلاً :


أهم دالتين هما هنا DoWork والذي يتم استدعاءه وقت بدء التنفيذ ، والحدث RunWorkerCompleted والذي يتم اطلاقه بعد الانتهاء من التنفيذ بالشكل التالي مثلاً :

C#:

كود :
private void ProcessNumbersBackgroundWorker_DoWork(object sender,
DoWorkEventArgs e)
{
}
private void ProcessNumbersBackgroundWorker_RunWorkerCompleted(object sender,
RunWorkerCompletedEventArgs e)
{
}
vb.net :


كود :
Private Sub ProcessNumbersBackgroundWorker_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs)
End Sub
Private Sub ProcessNumbersBackgroundWorker_RunWorkerCompleted(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs)
End Sub
لاحقاً يتم البدء بالتنفيذ بالشكل التالي :

كود :
ProcessNumbersBackgroundWorker.RunWorkerAsync(args);
حيث يتم تنفيذ الكود الموجود في الحدث DoWork .

والله الموفق ...
والسلام عليكم ورحمة الله وبركاته .
}}}
تم الشكر بواسطة:



التنقل السريع :


يقوم بقرائة الموضوع: بالاضافة الى ( 1 ) ضيف كريم