مشاركة عبر


مدارة مؤشر الترابط التشعبي أفضل الممارسات

يتطلب متعدد العمليات برمجة حذراً. معظم المهام، يمكنك تقليل درجة تعقيد بواسطة طلبات قائمة الانتظار لتنفيذ بواسطة مؤشر ترابط تجمع مؤشرات الترابط. يعالج هذا الموضوع أصعب المواقف، مثل كـ تنظيم العمل لمؤشرات ترابط متعددة، أو معالجة عمليات جزئية هذه الكتلة.

ملاحظةملاحظة

.NET Framework الإصدار 4، مكتبة متوازى المهام و PLINQ توفر واجهات برمجة التطبيقات التي تقلل بعض التعقيد ومخاطر البرمجة متعددة مؤشرات الترابط.لمزيد من المعلومات، راجع البرمجة المتوازية في .NET Framework.

حالات السباق و deadlocks

متعدد العمليات بحل المشاكل المتعلقة بإنتاجية و استجابة، ولكن في القيام بحيث أنه يقدم مشاكل جديدة: deadlocks و race الشروط.

deadlocks

تحدث حالة توقف تام عند كل من عمليات جزئية بين محاولة قفل مورد غير ذلك له مؤمنة بالفعل. يمكن جعل مؤشر ترابط ولا أي تقدم آخر.

توفر العديد من وظائف الفئات مؤشر الترابط المدارة المهلات إلى المساعدة في الكشف عن deadlocks. تشغيل سبيل المثال، ما يلي تعليمات برمجية يحاول الحصول تشغيل قفل تشغيل المثيل الحالي. في حالة التأمين هو لا الحصول عليها في millهوeconds 300 Monitor.TryEnterبإرجاع خطأ .

If Monitor.TryEnter(Me, 300) Then
    Try
        ' Place code protected by the Monitor here.
    Finally
        Monitor.Exit(Me)
    End Try
Else
    ' Code to execute if the attempt times out.
End If
if (Monitor.TryEnter(this, 300)) {
    try {
        // Place code protected by the Monitor here.
    }
    finally {
        Monitor.Exit(this);
    }
}
else {
    // Code to execute if the attempt times out.
}

شروط السباق

وجود حالة تعارض هو خطأ الذي يحدث عند حصيلة برنامج يعتمد تشغيل أي من مؤشري ترابط أو أكثر تصل إلى حظر معينة من تعليمات برمجية أول. قم بتشغيل البرنامج عدة مرة/مرات تعطي نتائج مختلفة، و لا يمكن توقعها نتيجة لتشغيل أي معطى.

مثال بسيط السباق شرط هو تزايد حقل. فرض فئة لها خاصة ثابتة حقل ( المشتركة في Vهوual الأساسية) التي هو زيادة وقت كل مثيل للفئة هو تم إنشاؤها، باستخدام تعليمات برمجية مثل objCt++;(C#) أو objCt += 1(Vهوual أساسى). تتطلب هذه تشغيل تحميل القيمة من objCtفي تسجيل، قم بزيادة القيمة، و تخزينها في objCt.

في أحد تطبيقات ذات مؤشرات ترابط متعددة، ومؤشر ترابط الذي قام بتحميل و يزداد قد تكون القيمة فقبل مؤشر ترابط آخر الذي يقوم بإجراء الجميع الخطوات الثلاث؛ وعند استئناف مؤشر الترابط أول لتنفيذ و يقوم بتخزين القيمة الخاصة به، فإنه يتم الكتابة فوق objCtبدون أخذ في الاعتبار الحقائق التي تم تم تغييره القيمة في المؤقتة.

Th هو حالة تنافس معينة هو avoided بسهولة باستخدام وظائف Interlockedللفئات، مثل Interlocked.Increment. إلى القراءة حول التقنيات الأخرى مزامنة بيانات بين مؤشرات ترابط متعددة، راجع من مزامنة بيانات ل متعدد العمليات.

يمكن أن يحدث حالات السباق أيضا عند يزامن أنشطة متعددة عمليات جزئية. كلما قمت بكتابة سطر من تعليمات برمجية، يجب مراعاة ما قد يحدث إذا تم فمؤشر ترابط قبل تنفيذ الخط (أو قبل أي من الإرشادات آلة الفردية التي تشكل الخط)، و overtook من مؤشر ترابط آخر.

رقم من معالجات

متعدد العمليات حل مشاكل مختلفة لأجهزة الكمبيوتر معالج فردي تعمل معظم البرامج للمستخدم النهائي، و أجهزة الكمبيوتر متعددة المعالجات بشكل عام المستخدمة كملقمات.

مفرد-أجهزة الكمبيوتر المعالج

متعدد العمليات يوفر استجابة أكبر للمستخدم الكمبيوتر ويستخدم خاملة الوقت لمهام في الخلفية. إذا كنت استخدم متعدد العمليات تشغيل جهاز كمبيوتر بمعالج فردي:

  • تشغيل مؤشر ترابط واحد فقط في أي الفورية.

  • تنفيذ مؤشر ترابط الخلفية فقط حين مؤشر الترابط الرئيسي مستخدم هو الخمول. مؤشر ترابط أمامي الذي ينفذ باستمرار starves خلفية عمليات جزئية من وقت المعالج.

  • عندما تقوم باستدعاء Thread.Startأسلوب في مؤشر ترابط، مؤشر الترابط هذا لم يبدأ تنفيذ حتى تعطي مؤشر الترابط الحالي أو هو فحسب النظام التشغيل.

  • تحدث حالات السباق عادة نظراً للمبرمج بالدخول لا تتوقع حقيقة فمؤشر ترابط في لحظة awkward، في بعض الأحيان مما يسمح لمؤشر ترابط آخر للوصول إلى حظر التعليمات برمجية أولاً.

أجهزة الكمبيوتر ذات المعالجات المتعددة

يوفر متعدد العمليات إنتاجية أكبر. معالجات عشرة يمكن القيام بأعمال عشر مرة/مرات واحد، ولكن فقط إذا كان العمل هو تقسيم حيث الجميع 10 يمكن أن تعمل في نفس الوقت؛ وتوفر مؤشرات الترابط بطريقة سهلة لتقسيم العمل واستغلال طاقة معالجة إضافية. إذا كنت تستخدم متعدد العمليات تشغيل جهاز كمبيوتر متعدد المعالجات:

  • عدد عمليات جزئية التي يمكن تنفيذها بشكل متزامن هو محدد بعدد المعالجات.

  • تنفيذ مؤشر ترابط الخلفية مؤشرات فقط عندما عدد المقدمة ترابط تنفيذ هو أقل من عدد المعالجات.

  • عندما تقوم باستدعاء Thread.Startأسلوب في مؤشر ترابط، مؤشر الترابط هذا قد أو قد لا يتم تشغيل ينفذ مباشرة، اعتماداً على عدد المعالجات و عدد عمليات جزئية قيد انتظار ينفذ.

  • يمكن أن تحدث حالات السباق ليس فقط لأنه يتم فمؤشرات الترابط بشكل غير متوقع، ولكن نظراً لأن الثاني مؤشرات ترابط التنفيذ تشغيل مختلف المعالجات قد تكون السباق للوصول إلى حظر تعليمات برمجية نفسها.

الأعضاء ثابتة المنشئات الثابتة

لم تتم تهيئة فئة حتى الدالة الإنشائية الفئة الخاص به (staticالدالة الإنشائية في C#, Shared Sub Newفي Visual أساسى) انتهاء تشغيل. لمنع تنفيذ تعليمات برمجية في نوع التي هو لم يتم تهيئة، يقوم وقت تشغيل اللغة العامة حظر الجميع المكالمات من عمليات جزئية الأخرى إلى staticالأعضاء الفئة ( Sharedالأعضاء في Vهوual الأساسية) حتى يكون الدالة الإنشائية الفئة لتشغيل finهوhed.

على سبيل المثال، إذا بدأت الدالة الإنشائية فئة مؤشر ترابط جديد، و استدعاء إجراء مؤشر ترابط staticعضو الفئة، وكتل مؤشر ترابط جديد إلى أن تكتمل الدالة الإنشائية الفئة.

ينطبق هذا إلى أي نوع يمكن أن يحتوي staticconstrucإلىr.

عام توصيات

خذ بعين الاعتبار الإرشادات التالية عند استخدام عدة عمليات جزئية:

  • لا تستخدم Thread.Abortلينهي غير ذلك عمليات جزئية. إيقاف قبل الاكتمال بطلبه تشغيل مؤشر ترابط آخر هو akin بطرح استثناء في مسار تنفيذ ذلك، دون معرفة ما أشر مؤشر الترابط التي وصلت في المعالجة.

  • لا تستخدم Thread.Suspendو Thread.Resumeإلى مزامنة أنشطة متعددة عمليات جزئية. Do استخدمMutex,ManualResetEvent,AutoResetEvent, وMonitor.

  • عدم التحكم في تنفيذ مؤشرات ترابط العاملين من البرنامج الأساسي الخاص بك (استخدام الأحداث، مثال). بدلاً من ذلك، بتصميم البرنامج الخاص بك بحيث يمكن لمؤشرات ترابط العاملين وتعتبر مسؤولاً عن الانتظار حتى يتم العمل هو متوفرة، تنفيذ ذلك، وإعلام أجزاء غير ذلك من البرنامج الخاص بك عند finهوhed. إذا كانت مؤشرات ترابط العاملين الخاص بك لا حظر، خذ بعين الاعتبار استخدام مؤشرات ترابط تجمع مؤشر ترابط. Monitor.PulseAllهو مفيدة في حالات الموقع مؤشرات ترابط العاملين. حظر

  • لا تستخدم أنواع كـ تأمين الكائنات. هو تجنب تعليمات برمجية مثل كـ lock(typeof(X))في C# أو SyncLock(GetType(X))في Visual أساسى Bكـic، أو استخدم Monitor.Enterمع Typeالكائنات. لنوع محدد، هناك هو مثيل واحد فقط من System.Typeكل مجال تطبيق. في حالة القيام بتأمين تشغيل النوع هو العامة، تعليمات برمجية غير الخاصة بك يمكنك اتخاذها التأمين فيها، إلى deadlocks. من أجل مشاكل إضافى، راجع وثوقية أفضل الممارسات.

  • استخدم تنبيه عند تأمين تشغيل الأمثلة، تشغيل سبيل المثال lock(this)في C# أو SyncLock(Me)في Visual أساسى. إذا غير ذلك تعليمات برمجية في تطبيق الخاص بك، خارجي بالنوع، تأخذ بقفل الكائن، يمكن أن يحدث deadlocks.

  • ضمان مؤشر ترابط التي تم إدخالها جهاز دائماً بترك جهاز العرض هذا، حتى في حالة حدوث استثناء أثناء مؤشر الترابط هو في جهاز العرض. يوفر C#‎ قفل العبارة والعبّارة SyncLock Vهوual الأساسية th هو استخدام على أخيرا منع سلوك تلقائياً، للتأكد من أن Monitor.Exitهو تسمى. إذا كان لا يمكن التأكد من ذلك إنهاء استدعاء، خذ بعين الاعتبار تغيير التصميم الخاص بك إلى استخدم كائن المزامنة. كائن مزامنة هو تلقائياً بإصدار عند إنهاء مؤشر ترابط الذي يملك عليه حاليا.

  • قم باستخدام مؤشرات ترابط متعددة لتنفيذ المهام التي تتطلب موارد مختلفة، وتجنب تعيين مؤشرات ترابط متعددة إلى مورد مفرد. على سبيل المثال، تفيدك أي المهام التي تشتمل على ادخال/اخراج من وجود مؤشر ترابط الخاص به، لأن مؤشر ترابط هذا سوف منع أثناء العمليات الادخال/الاخراج والسماح بذلك غير ذلك العمليات جزئية لتنفيذ. إدخال مستخدم هو مورد آخر الفوائد من مؤشر ترابط مخصص. تشغيل مفرد-كمبيوتر، coexists مهمة تتضمن حساب كبيرة بإدخال مستخدم والمهام التي تتضمن الادخال/الاخراج، ولكن contend عدة مهام الحساب بشكل كبير مع بعضها البعض.

  • يمكنك استخدام الوظائف الخاصة Interlockedفئة لتغيير الحالة البسيطة، بدلاً من استخدام lockكشف ( SyncLockفي Visual أساسى). lockجملة هو أداة العام بضاعة، ولكن Interlockedفئة يوفر أداء أفضل للتحديثات التي يجب أن يكون بسيط. داخليا، تنفيذ بادئة قفل واحدة إذا كان هناك هو عدم وجود منافسة. في مراجعة تعليمات برمجية، مراقبة للتعليمات البرمجية كتلك هو مبين في الأمثلة التالية. في المثال أول، يتم زيادة متغير الولاية:

    SyncLock lockObject
        myField += 1
    End SyncLock
    
    lock(lockObject) 
    {
        myField++;
    }
    

    يمكنك تحسين الأداء باستخدام Incrementأسلوب بدلاً من lockالعبارة، كما يلي:

    System.Threading.Interlocked.Increment(myField)
    
    System.Threading.Interlocked.Increment(myField);
    
    ملاحظةملاحظة

    في.NET Framework الإصدار 2.0، Addالأسلوب توفر التحديثات بسيط في زيادات بقعة صغيرة من 1.

    في المثال الثاني، نوع المرجع تحديث متغير فقط إذا كان مرجع فارغة ( Nothingفي Vهوual أساسى).

    If x Is Nothing Then
        SyncLock lockObject
            If x Is Nothing Then
                x = y
            End If
        End SyncLock
    End If
    
    if (x == null)
    {
        lock (lockObject)
        {
            if (x == null)
            {
                x = y;
            }
        }
    }
    

    الأداء can be improved بواسطة using the CompareExchange أسلوب instead, كـ follows:

    System.Threading.Interlocked.CompareExchange(x, y, Nothing)
    
    System.Threading.Interlocked.CompareExchange(ref x, y, null);
    
    ملاحظةملاحظة

    في the .NET الإصدار إطار العمل 2.0, the CompareExchange أسلوب has a generic التحميل الزائد that can be used for أمان النوع replacement of أي مرجع نوع.

Recommendations for فئة مكتبات

Consider the following guidelines when designing فئة مكتبات for متعدد العمليات:

  • Avoid the need for المزامنة, if possible. This هو especially صواب for heavily used تعليمات برمجية. For مثال, an خوارزمية might be adjusted إلى tolerate a حالة تعارض rather than eliminate it. Unnecessary المزامنة decreases الأداء و creates the possibility of deadlocks و race conditions.

  • جعل بيانات ثابتة ( Sharedفي Visual أساسى) مسار التنفيذ آمن بشكل افتراضي.

  • Do not make مثيل بيانات مؤشر ترابط آمن بواسطة الافتراضي. إضافة عمليات القفل لإنشاء مسار تنفيذ اﻷمن تعليمات برمجية انخفاض مستوى الأداء وزيادة قفل منافسة وينشئ الاحتمال لحدوث deadlocks. بشكل عام نماذج تطبيق، مؤشر ترابط واحد فقط في نفس وقت تنفيذ التعليمة البرمجية للمستخدم، مما يقلل الحاجة إلى أمان مؤشر الترابط. ولهذا السبب، مكتبات فئة.NET Framework غير مسار التنفيذ آمن بواسطة الافتراضي.

  • تجنب تقديم ثابت وظائف تبديل ثابت الالولاية. في سيناريو شائعة للخادم، الولاية ثابتة هو المشتركة عبر الطلبات، مما يعني أن مؤشرات ترابط متعددة يمكن تنفيذ تلك التعليمة البرمجية في نفس الوقت. يؤدي هذا إلى فتح لأعلى احتمال وجود ترابط الأخطاء. يمكنك استخدام نموذج تصميم تغليف بيانات في الحالات التي لا يتم مشاركتها عبر طلبات. علاوة على ذلك، إذا كانت تتم مزامنة بيانات الثابتة، المكالمات بين وظائف ثابتة تبديل الولاية يمكن النتيجة في deadlocks أو مزامنة زائدة، يؤثر بشكل سلبي التأثير على الأداء.

راجع أيضًا:

المبادئ

عمليات جزئية و مؤشر الترابط التشعبي

موارد أخرى

مدارة مؤشر الترابط التشعبي