سؤال

دعنا نقول أنني حصلت على بنية تتكون من 100 بايت. ما الضمانات التي حصلت عليها حول الكود التالي؟

m_myLargeStruct = someValue; // copying 100 bytes
Thread.MemoryBarrier();

// Executed by another thread, after "Thread.MemoryBarrier" was called by the first thread
Console.WriteLine(m_myLargeStruct.ToString());

هل تضمن نموذج الذاكرة أن نسخ 100 بايت ستكون كاملة بعد وضع حاجز الذاكرة؟ أو قم بتطبيق حواجز الذاكرة فقط على الأنواع الموجودة في حجم بنية المعالج؟ (4 بايت ل 32 بت و 8 بايت إلى 64 بت).
هل هذا هو السبب في متغير الكلمة الرئيسية تنطبق فقط على أنواع البدائية؟ (إذا قمت بالإعلان عن عضوا 8 بايت كمتقللا، فهذا يعني أنه سيتم استخدام جهاز مشتقر متشابك لتغيير قيمةه؟ [منذ أن لا تكون ذرية مضمونة لأنواع أكبر من 4 بايت على آلات 32bit]).

آمل أن أكون واضحا بما فيه الكفاية .. :)
شكرًا

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

المحلول

من الواضح أن الجواب هو لا, ، أو بالأحرى، ليس لديك ضمانات حول أي شيء. لا شيء يمنع نظام التشغيل من تبديل الخيط الذي يكتب إلى بنية 100 بايت قبل بدء تشغيل مؤشر الترابط الذي يطبع بنية 100 بايت.

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

نصائح أخرى

ما لم يكن موضوع القراءة لديه حاجز الذاكرة أيضا، أنا لا فكر في سوف تساعدك كثيرا.

شخصيا سأخجل من:

  • الهياكل التي هي كبيرة
  • الحصول على عميق في نموذج الذاكرة لكتابة رمز خالية من القفل

... ما لم يكن لديك سبب مهم حقا للقيام بذلك. إنه باهظ من الصعب الحصول على الترميز الخالي من القفل مباشرة مع بيانات قابلة للتغيير؛ أعتقد أنه حتى الخبراء يكافحون. عادة ما أجد أن "أخذ قفل لكل كتلة الوصول إلى البيانات" أسهل في الحصول على حق فهي على ما يرام من حيث الأداء لمدة 99٪ من الحالات.

أنا أثق في فريق PFX في Microsoft للحصول على ترميز الترميز الخالي من قفل القفل، وله من أجل تزويد لي بطريقات WTH يمكنني استخدام التعليمات البرمجية الخاصة بها لكتابة برامج الأقفال الخاصة بي بسهولة نسبيا. أنا لا أثق بنفسي للحصول على هذا النوع من الشيء الصحيح. إذا كنت بحاجة إلى استخدام حاجز الذاكرة بشكل صريح، فربما يعني ذلك أنني أحاول بشدة.

تحتاج إلى حاجز ذاكرة آخر في الخيط الثاني قبل الكتابة. (إذا كان نظامك يوفر حواجز ذاكرة غير متماثلة، فهذا يكفي تنفيذ حاجز الإصدار بعد التعيين وحاجز الحصول على حاجز قبل الكتابة).

حجم البيانات لا يهم.

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

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

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

حسنا، أولا وقبل كل شيء، يجب أن لا يكون لديك بنية هذا كبير. إلا إذا كنت حذرا للغاية حول كيفية استخدامك من الهيكل، فستكون أبطأ من استخدام الفصل. أيضا، إنها مضادة بديهية إلى دلالات القيمة من الهياكل.

ومع ذلك، فإن حاجز الذاكرة سوف يضمن أن يتم نسخ الهيكل. لن يتحرك الأمثل أي تعليمات عبر الحاجز.

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

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