سؤال

كيف يمكنك تنفيذ كفاءة موضوع آمنة الإشارة نظام العد على X86 وحدة المعالجة المركزية في لغة البرمجة C++?

لطالما واجهت مشكلة أن العمليات الهامة ليس الذرية, و المتاحة X86 التعشيق العمليات ليست كافية لتنفيذ الحكم نظام العد.

المقالة التالية يغطي هذا الموضوع ، ولكن يتطلب خاص تعليمات وحدة المعالجة المركزية:

http://www.ddj.com/architect/184401888

هل كانت مفيدة؟

المحلول

في الوقت الحاضر يمكنك استخدام دفعة/TR1 shared_ptr<> مؤشر ذكية للحفاظ على مرجع حساب المراجع.

يعمل كبيرة ؛ أي ضجة ، لا فوضى.على shared_ptr<> الدرجة تأخذ الرعاية من كل تأمين حاجة على refcount.

نصائح أخرى

في VC++, يمكنك استخدام _InterlockedCompareExchange.

do
   read the count
   perform mathematical operation
   interlockedcompareexchange( destination, updated count, old count)
until the interlockedcompareexchange returns the success code.

على منصات أخرى/المجمعين ، واستخدام المناسبة الذاتية على قفل CMPXCHG تعليمات MS _InterlockedCompareExchange يعرض.

بالمعنى الدقيق للكلمة, سوف تحتاج إلى الانتظار حتى C++0x أن يكون قادرا على كتابة موضوع آمن رمز في نقي C++.

الآن يمكنك استخدام Posix ، أو إنشاء الخاصة بك منصة مستقلة مغلفة حول مقارنة ومبادلة و/أو متشابكة زيادة/إنقاص.

Win32 InterlockedIncrementAcquire و InterlockedDecrementRelease (إذا كنت تريد أن تكون آمنة و يهتمون منصات مع إمكانية إعادة ترتيب ، وبالتالي تحتاج إلى مسألة الذاكرة الحواجز في نفس الوقت) أو InterlockedIncrement و InterlockedDecrement (إذا كنت متأكدا من أنك سوف البقاء x86) ، الذرية سيتم القيام بهذه المهمة.

وقال دفعة/TR1 shared_ptr<> سيتم التعامل مع كل هذا بالنسبة لك, لذلك إلا إذا كنت بحاجة إلى تنفيذ ذلك بنفسك, وربما كنت سوف تفعل أفضل التمسك بها.

نضع في اعتبارنا أن تأمين غالية جدا و يحدث في كل مرة كنت اليد الكائنات حولها بين المؤشرات الذكية - حتى عند الكائن المملوكة حاليا من قبل مؤشر ترابط واحد (الذكية مؤشر المكتبة لا يعرف ذلك).

ونظرا لهذا ، قد يكون هناك قاعدة عامة تنطبق هنا (أنا سعيدة إلى تصحيح!)

إذا الأشياء التالية تنطبق عليك:

  • لديك هياكل البيانات المعقدة التي من شأنها أن يكون من الصعب كتابة المتلفات (أو حيث STL-أسلوب القيمة دلالات سيكون من غير المناسب ، حسب التصميم) لذلك تحتاج المؤشرات الذكية أن تفعل ذلك بالنسبة لك ،
  • كنت تستخدم مؤشرات الترابط المتعددة التي تتقاسم هذه الكائنات ،
  • يهمك الأداء وكذلك صحة

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

لا ref-العد:

a = b;

المرجع العد:

if (a != null)
    if (InterlockedDecrement(ref a.m_ref) == 0)
            a.FinalRelease();

if (b != null)
    InterlockedIncrement(ref b.m_ref);

a = b;

إذا كان التعليم في حد ذاته ليس الذرية ثم تحتاج إلى جعل قسم الكود الذي التحديثات المناسبة متغير مقطع حرج.

أي تحتاج إلى منع المواضيع الأخرى دخول هذا القسم من التعليمات البرمجية باستخدام بعض قفل المخطط.بالطبع الأقفال تحتاج إلى أن تكون الذرية ، ولكن يمكنك أن تجد ذرية قفل آلية داخل pthread_mutex الدرجة.

مسألة كفاءة:على pthread مكتبة فعالة كما يمكن أن يكون لا يزال ضمان أن مزامنة قفل الذرية لنظام التشغيل الخاص بك.

هو أنها مكلفة:ربما.ولكن كل ما يتطلب ضمان هناك تكلفة.

خاصة أن قانون نشر في هذا ddj المادة هو إضافة المزيد من التعقيد إلى الحساب عن الخلل في استخدام المؤشرات الذكية.

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

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top