لماذا لا يوجد الزائد متشابكة.إضافة يقبل يضاعف من المعلمات ؟

StackOverflow https://stackoverflow.com/questions/1400465

سؤال

أنا نقدر atomicity أن خيوط.متشابكة الدرجة يقدمها ؛ أنا لا أفهم ذلك ، لماذا إضافة وظيفة يقدم سوى اثنين الزائدة:واحد الاعداد الصحيحه, آخر يتوق.لماذا لا الزوجي ، أو أي نوع عددي لهذه المسألة ؟

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

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

المحلول

ويلتف الطبقة متشابكة حول وظائف ** متشابكة ويندوز API.

وهذه هي، في المقابل، التفاف حول API معالج الأصلي، وذلك باستخدام بادئة تعليمات LOCK ل x86. إلا يدعم التقديم التعليمات التالية:

<اقتباس فقرة>   

وBT، BTS، BTR، BTC، XCHG، XADD، إضافة، OR، ADC، SBB، AND، SUB، XOR، NOT، NEG، INC، ديسمبر

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

وهنا كبيرة من المادة مناقشة دلالات قفل على مستوى تعليمات .

نصائح أخرى

وتناولت أخرى "لماذا؟". فمن السهل ولكن للفة Add(ref double, double) الخاصة بك، وذلك باستخدام CompareExchange بدائية:

public static double Add(ref double location1, double value)
{
    double newCurrentValue = location1; // non-volatile read, so may be stale
    while (true)
    {
        double currentValue = newCurrentValue;
        double newValue = currentValue + value;
        newCurrentValue = Interlocked.CompareExchange(ref location1, newValue, currentValue);
        if (newCurrentValue == currentValue)
            return newValue;
    }
}

وCompareExchange يحدد قيمة location1 أن newValue، إذا كانت القيمة الحالية يساوي currentValue. وهي إذ تفعل ذلك بطريقة الذرية، ذات ألوان، لا يمكننا الاعتماد عليه وحده دون اللجوء إلى الأقفال.

لماذا حلقة while (true)؟ حلقات من هذا القبيل هي المعيار عند تنفيذ الخوارزميات المتزامنة بتفاؤل. سوف CompareExchange لا تغيير location1 إذا كانت القيمة الحالية تختلف عن currentValue. I تهيئة currentValue إلى location1 - القيام قراءة غير المتطايرة (التي قد تكون قديمة، ولكن هذا لا يغير من صحة، وCompareExchange سوف تحقق قيمة). إذا كانت القيمة الحالية (لا يزال) هو ما قد قرأنا من location، سوف CompareExchange تغيير القيمة إلى newValue. إذا لم يكن كذلك، لدينا لإعادة محاولة CompareExchange مع القيمة الحالية الجديدة، على النحو الذي عاد CompareExchange.

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

وكما قال ريد Copsey، خريطة عمليات متشابكة (عبر وظائف API Windows) لدعم تعليمات مباشرة من معالجات x86 / إلى x64. وبالنظر إلى أن واحدة من تلك الوظائف هو XCHG، يمكنك القيام بعملية XCHG الذرية دون الاهتمام حقا ما بت في الموقع المستهدف تمثل. وبعبارة أخرى، يمكن رمز "التظاهر" أن عدد النقطة العائمة 64 بت كنت تبادل هو في الواقع صحيح 64 بت، وسوف تعليمات XCHG لا يعرف الفرق. وهكذا، يمكن أن صافي توفير وظائف Interlocked.Exchange ليطفو والزوجي ب "التظاهر" بأنهم الأعداد الصحيحة والأعداد الصحيحة طويلة، على التوالي.

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

وأظن أن هناك نوعان من الأسباب.

  1. المعالجات المستهدفة .صافي الدعم متشابكة الزيادة فقط صحيح الأنواع.وأعتقد أن هذا هو قفل البادئة على x86, ربما تعليمات مماثلة موجودة المعالجات الأخرى.
  2. إضافة إلى النقطة العائمة عدد يمكن أن يؤدي في نفس العدد إذا كان كبيرا بما فيه الكفاية ، لذلك أنا لست متأكدا مما إذا كان يمكنك استدعاء هذا زيادة.ربما إطار المصممين يحاولون تجنب nonintuitive السلوك في هذه الحالة.
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top