التنبيهات التالية ظهرت :
Warning [2] count(): Parameter must be an array or an object that implements Countable - Line: 864 - File: showthread.php PHP 7.4.33 (Linux)
File Line Function
/showthread.php 864 errorHandler->error



تقييم الموضوع :
  • 0 أصوات - بمعدل 0
  • 1
  • 2
  • 3
  • 4
  • 5
تزامن المسارات Thread Synchronization
#1
كاتب الموضوع : samerselo

The SyncLock Statement

خلال زمن التشغيل لا يوجد شئ يضمن لك أن يسير الكود بشكل نظامي بدون مقاطعات وتكون عملية التشغيل بدون مقاطعات عملية قاسية على نظام التشغيل وخاصة عندما يكون عبارة عن بيئة متعددة المهام وفي معظم الحالات التي ستحتاجها ستكون قانعا بالدقة ضمن البرنامج الواحد وذلك عند معالجة الكود فعلى سبيل المثال يكون كافيا لك ضمان أن مسار تنفيذ واحد ضمن التطبيق الحالي يستطيع تنفيذ قطعة معينة من الكود في وقت محدد ويمكنك تحقيق ذلك بتضمين قطعة الكود تلك ضمن كتلة SyncLock…End SyncLock والذي يحتاج إلى متغير كمحدد له محققا المتطلبات التالية:
• يجب أن يكون مشترك بين جميع المسارات ويكون في العادة متغير على مستوى الفئة وبدون الخاصية ThreadStatic
• يجب أن يكون من نوع مرجعي مثل String أو Object واستخدام أنواع القيمة ينتج عنه خطأ في الترجمة
• يجب أن لا يحتوي على القيمة Nothing وفي حال تمرير القيمة Nothing سيسبب أخطاء في زمن التنفيذ
وفيما يلي مثال عن كتلة SyncLock

كود :
' The lock object. (Any non-Nothing reference value will do.)
Private consoleLock As New Object()

Sub SynchronizationProblem_Task(ByVal obj As Object)
Dim number As Integer = CInt(obj)
' Print a lot of information to the console window.
For i As Integer = 1 To 1000
SyncLock consoleLock
' Split the output line in two pieces.
Console.Write(" ")
Console.Write(number)
End SyncLock
Next
End Sub
والكود السابق يستخدم المتغير consoleLock للتحكم بالوصول للغرض Console وهو يشكل المصدر الوحيد المشترك بين جميع المسارات في المثال ولهذا فهو المصدر الذي يجب عليك تحقيق التزامن من أجله والتطبيقات الحقيقية يمكن أن تحوي العديد من كتل SyncLock والتي يمكن أن تستخدم نفس المتغير المحلي أو عدة متغيرات مختلفة من أجل اختلاف البصمة وهنا يجب عليك استخدام متغيرا مميزا من أجل كل نوع من أنواع المصادر المشتركة التي يجب عمل التزامن من اجلها أو من أجل مجموعة التعابير التي يجب تنفيذها ضمن المسار في نفس الوقت.
وعندما تستخدم كتلة SyncLock يتضمن الكود تلقائيا كتلة Try…End Try مخفية من أجل ضمان تحرير القفل بشكل صحيح إذا تم إطلاق استثناء ومن أجل هذا لا يمكنك القفز لعبارة داخل الكتلة SyncLock. وإن كانت الكتلة SyncLock موضوعة داخل إجراء خاص بتواجد Instance لفئة ما وجميع المسارات العاملة ضمن إجراء في ذلك التواجد Instance للفئة يمكنك تمرير Me لعبارة الـ SyncLock وذلك بسبب أن هذا الغرض يحقق كل المتطلبات (يمكن الوصول إليه من جميع المسارات – وهو قيمة مرجعية – وبالتأكيد هو ليس Nothing)

كود :
Class TestClass
Sub TheTask()
SyncLock Me
' Only one thread at a time can access this code.

End SyncLock
End Sub
End Class
ملاحظة: يمكنك استخدام Me بهذه الطريقة فقط إن كنت تريد عمل التزامن على مصدر وحيد كملف محدد مثلا أو نافذة الكونسول Console Window وإن كان لديك عدة كتل تزامن التي تحمي عدة مصادر ستستخدم بشكل تلقائي عدة متغيرات كبارامترات لكتلة SyncLock. والشئ الذي له أهمية أكبر مما ذكر هو أنه يجب عليك استخدام Me كبارامتر فقط إذا كانت الفئة غير مرئية خارج المجمع الحالي عدا ذلك يمكن لتطبيق آخر استخدام نفس التواجد Instance للفئة ضمن كتلة SyncLock مختلفة وبهذا فلن يتم تنفيذ عدة كتل من الكود بدون سبب حقيقي محدد وبشكل عام لا يجب عليك استخدام غرض Object عام مرئي من مجمعات أخرى كبارامتر لكتلة SyncLock. وتجدر الملاحظة أن العديد من الأكواد التي تراها على الانترنت تستخدم العامل GetType للحصول على نوع الغرض المستخدم للقفل lock object وذلك لحماية الطريقة الساكنة.
عندما تستخدم عبارات SyncLock معششة للقيام بالتزامن لأغراض مختلفة من الضروري استخدام تسلسل تعشيش متطابق أينما احتجت له في تطبيقك فالتحري عن الأقفال بالتسلسل المطابق ذاته يجنبك الوصول إلى حالة الأقفال الميتة خلال العديد من أجزاء التطبيق وهذه القاعدة تنطبق أيضا عندما تقوم دالة تحتوي على SyncLock باستدعاء دالة أخرى تحتوي على SyncLock

كود :
' Always use this sequence when locking objLock1 and objLock2.
SyncLock objLock1
SyncLock objLock2

End SyncLock
End SyncLock
اعتبارات الأداء والتواجد الكسول Performance Considerations and Lazy Instantiation
تضمين جميع الأكواد التي تستخدم متغيرات مشتركة ضمن كتلة SyncLock يؤدي إلى إبطاء تطبيقك كثيرا أو تخفيض أداؤه بشكل ملحوظ وبشكل خاص عندما يتم تشغيله على حاسب متعدد المعالجات فإن استطعت تجنب استخدام كتلة SyncLock بدون تعريض تكامل البيانات للخطر يجب عليك القيام به قطعيا فمثلا تخيل أنك تستخدم نمط وحيد بتواجد كسول lazy instantiation في بيئة متعددة المسارات

كود :
Public Class Singleton
Private Shared m_Instance As Singleton
Private Shared sharedLock As New Object()

Public Shared ReadOnly Property Instance() As Singleton
Get
SyncLock sharedLock
If m_Instance Is Nothing Then m_Instance = New Singleton
Return m_Instance
End SyncLock
End Get
End Property
End Class
تكمن المشكلة في الكود السابق أن معظم الوصولات للخاصية لا يحتاج إلى تزامن وذلك لأن المتغير الخاص m_Instance يتم تعيينه مرة واحدة في المرة الأولى التي يتم فيها قراءة الخاصية وفي ما يلي طريقة أفضل لتحقيق التصرف المطلوب

كود :
Class Singleton
Private Shared m_Instance As Singleton
Private Shared sharedLock As New Object

Public Shared ReadOnly Property Instance() As Singleton
Get
If m_Instance Is Nothing Then
SyncLock sharedLock
If m_Instance Is Nothing Then m_Instance = New Singleton()
End SyncLock
End If
Return m_Instance
End Get
End Property
End Class
الأغراض المتزامنة Synchronized Objects
مشكلة أخرى متعلقة بالمسارات في الدوت نيت هي أن ليس جميع أغراض الدوت نيت .NET object قابلة للمشاركة بأمان عبر المسارات not all .NET objects are thread-safeفعندما تقوم بكتابة تطبيق متعدد المسارات يجب عليك التأكد دوما من الوثائق للتأكد من أن الأغراض والطرائق التي تستخدمها آمنة للاستخدام عبر المسارات فعلى سبيل المثال جميع الطرق الساكنة للفئات Regex و Match أمنة عبر المسارات ولكن الطرق الغير ساكنة غير آمنة فيجب عدم استخدامها ضمن مسار مختلف وكذلك بعض أغراض الدوت نيت مثل Windows Forms objects and controls لها العديد من الحدود التي تجعل فقط المسار الذي أنشأها يمكنه استدعاء طرقها وخصائصها

أنواع دوت نيت المتزامنة Synchronized .NET Types
العديد من الأغراض الغير آمنة عبر المسارات بطبيعتها مثل ArrayList و Hashtable و Queue و SortedList و Stack و TextReader و TextWriter و التعابير النظامية تقدم طريقة ساكنة قابلة للتزامن تعيد غرض أمن للمسارات thread-safe object مكافئ للذي تم تمريره كما أن معظمها يعرض الخاصية IsSynchronized التي تعيد True عندما تتعامل مع نسخة آمنة عبر المسارات

كود :
' Create an ArrayList object, and add some values to it.
Dim al As New ArrayList()
al.Add(1): al.Add(2): al.Add(3)
' Create a synchronized, thread-safe version of this ArrayList.
Dim syncAl As ArrayList = ArrayList.Synchronized(al)
' Prove that the new object is thread-safe.
Console.WriteLine(al.IsSynchronized) ' => False
Console.WriteLine(syncAl.IsSynchronized) ' => True
' You can now share the syncAl object among different threads
تذكر دائما أن التعامل مع هذه النسخة المتزامنة يكون أبطأ من النسخة الغير متزامنة وذلك بسبب أن كل طريقة تمر عبر سلسلة من الفحوصات الداخلية وفي معظم الحالات يمكنك كتابة كود فعال أكثر إذا استخدمت المصفوفات والمجموعات العادية regular arrays and collections وقمت بمزامنة عناصرها باستخدام كتلة SyncLock العادية

The Synchronization Attribute
استخدام الخاصية System.Runtime.Remoting.Contexts.Synchronization هي أبسط طريقة لتحقيق الوصول المتزامن للغرض Object بأكمله وبذلك يستطيع مسار واحد فقط الوصول إلى حقوله وطرائقه وبذلك أي مسار يستطيع استخدام الفئة ولكن مسار واحد فقط يستطيع تنفيذ أحد طرائقه إذا كانت الطريقة تنفذ كودا ضمن الفئة Class وأي مسار يحاول استخدام هذه الفئة عليه الانتظار وبكلمات أخرى وكأن هناك كتل SyncLock تغلف كافة طرائق الفئة مستخدمة نفس متغير الإقفال. والكود التالي يبين كيف يمكنك مزامنة فئة باستخدام الخاصية Synchronization attribute لاحظ أيضا أن الفئة يجب أن يتم وراثتها من ContextBoundObject ليتم تعليمها كـ context-bound object

كود :
System.Runtime.Remoting.Contexts.Synchronization()> _
Class Display
Inherits ContextBoundObject

End Class
و خاصية التزامن Synchronization attribute تضمن الوصول المتزامن لجميع الحقول والخصائص والطرق ولكنها لا توفر التزامن للأعضاء الساكنين static members وهي تأخذ بارامترا اختياريا يمكن أن تكون قيمته True أو False أو أحد الثوابت التي توفرها الفئة SynchronizationAttribute والتي يمكنك الاطلاع عليها من مكتبة MSDN
}}}
تم الشكر بواسطة:


الردود في هذا الموضوع
تزامن المسارات Thread Synchronization - بواسطة Raggi Tech - 03-10-12, 08:33 AM

المواضيع المحتمل أن تكون متشابهة .
الموضوع : الكاتب الردود : المشاهدات : آخر رد
  التعامل مع Resources و image list الاستغناء عن المسارات RaggiTech 1 3,250 02-10-12, 10:58 AM
آخر رد: RaggiTech
  استخدام بحيرة المسارات Using the Thread pool RaggiTech 0 2,143 02-10-12, 01:36 AM
آخر رد: RaggiTech
  Thread Methods & Proprties & Attributes RaggiTech 0 1,691 01-10-12, 07:33 PM
آخر رد: RaggiTech

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


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