multithreading - معنى - what is thread




ھل یقوم أحد تعلیمات المجمع بالتنفیذ دائما؟ (8)

اليوم جئت عبر هذا السؤال:

لديك رمز

static int counter = 0;
void worker() {
    for (int i = 1; i <= 10; i++)
        counter++;
}

إذا كان سيتم استدعاء worker من اثنين من المواضيع المختلفة، ما هي قيمة سوف يكون لها بعد أن انتهت كل منهما؟

وأنا أعلم أنه في الواقع يمكن أن يكون أي شيء. ولكن الشجاعة الداخلية تقول لي، أن counter++ سوف تترجم على الأرجح إلى تعليمات المجمع الواحد، وإذا كان كل من الخيوط تنفذ على نفس الأساسية، سيكون counter 20.

ولكن ماذا لو تم تشغيل هذه المواضيع على النوى أو المعالجات المختلفة، هل يمكن أن يكون هناك شرط السباق في ميكروكود؟ هل يمكن دائما النظر إلى تعليم المجمع على أنه عملية ذرية؟


  1. عمليات الزيادة / النقصان على 32 بت أو أقل من المتغيرات الصحيحة على معالج واحد 32 بت مع عدم وجود تقنية خيوط المعالجة هي ذرية.
  2. على معالج مع تقنية هايبر-ثرادينغ أو على نظام متعدد المعالجات، لا يتم ضمان عمليات الزيادة / النقصان ليتم تنفيذها أتوميكالي.

أعتقد أنك ستحصل على حالة سباق على الوصول.

إذا كنت ترغب في ضمان عملية ذرية في زيادة عداد ثم كنت بحاجة إلى استخدام ++ العداد.


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

لهذا الغرض، هناك حواجز الذاكرة ( http://en.wikipedia.org/wiki/Memory_barrier )

وباختصار، في حين أن التعليمات الذرية كافية على إنتل (مع البادئات القفل ذات الصلة)، يجب أن يتم المزيد على غير إنتل، لأن الذاكرة I / O قد لا تكون في نفس الترتيب.

هذه مشكلة معروفة عند نقل حلول "خالية من القفل" من إنتل إلى أبنية أخرى.

(لاحظ أن أنظمة متعددة المعالجات (وليس متعددة النواة) على x86 يبدو أيضا بحاجة إلى حواجز الذاكرة، على الأقل في وضع 64 بت.


على وجه التحديد ل x86، وفيما يتعلق بك المثال: counter++ ، وهناك عدد من الطرق التي يمكن تجميعها. المثال الأكثر تافهة هو:

inc counter

وهذا يترجم إلى العمليات الجزئية التالية:

  • تحميل counter إلى سجل مخفي على وحدة المعالجة المركزية
  • زيادة السجل
  • تخزين السجل المحدث في counter

هذا هو أساسا نفس:

mov eax, counter
inc eax
mov counter, eax

لاحظ أنه إذا كان بعض التحديثات وكيل آخر counter بين الحمل ومخزن، فإنه لن ينعكس في counter بعد المخزن. يمكن أن يكون هذا العامل موضوع آخر في نفس الأساسية، نواة أخرى في نفس وحدة المعالجة المركزية، وحدة المعالجة المركزية آخر في نفس النظام، أو حتى بعض وكيل خارجي يستخدم دما (الوصول إلى الذاكرة المباشرة).

إذا كنت تريد التأكد من أن هذا inc ذري، استخدم بادئة lock :

lock inc counter

lock يضمن أن لا أحد يستطيع تحديث counter بين التحميل والمخزن.

فيما يتعلق بالتعليمات الأكثر تعقيدا، لا يمكنك عادة افتراض أنها ستنفذ ذريا، إلا إذا كانت تدعم بادئة lock .


في معظم الحالات، لا . في الواقع، على x86، يمكنك تنفيذ التعليمات

push [address]

والتي، في C، سيكون شيئا مثل:

*stack-- = *address;

يؤدي هذا نقل الذاكرة اثنين في تعليمات واحدة .

هذا من المستحيل أساسا القيام به في 1 دورة على مدار الساعة، وليس أقلها لأن نقل الذاكرة واحد هو أيضا غير ممكن في دورة واحدة!


قد لا يكون إجابة فعلية على سؤالك، ولكن (على افتراض أن هذا هو C # أو لغة .NET أخرى) إذا كنت تريد counter++ لتكون حقا ذري متعددة الخيوط، يمكنك استخدام System.Threading.Interlocked.Increment(counter) .

انظر إجابات أخرى عن المعلومات الفعلية على العديد من الطرق المختلفة لماذا / كيف counter++ لا يمكن أن تكون ذرية. ؛-)


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


ليس دائما - في بعض المعماريات يتم ترجمة تعليمات التجميع إلى التعليمات البرمجية للماكينة الواحدة، بينما لا يتم ترجمتها على الآخرين.

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

استخدام تقنيات المزامنة المناسبة بدلا من ذلك، تعتمد على اللغة التي يتم الترميز في.





race-condition