مؤشرات الترابط Windows: متى يجب أن تستخدم interlockedexchangeadd ()؟

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

سؤال

يبدو أن تسمية هذه الوظيفة مثل هذه الأشياء المعقدة التي تحدث. عندما يعرف المرء بالضبط أن هذا هو الطريق للذهاب بدلاً من فعل شيء كهذا:

تحضيرCritice_Section CS ؛ int *p = malloc (sizeof (int)) ؛ // موقع التخصيص initializecriticalsection (& cs) ؛ // تلميح للكتابة أولاً

الموضوع رقم 1{ *p = 1 ؛ // أول كتابة}

الموضوع رقم 2{entercriticalSection (& cs) ؛ *ع = 2 ؛ // Second Write LeavecriticalSection (& cs) ؛ }

لدي كتابة تتم في موضوع واحد:

Run()
{
// some code
m_bIsTerminated = TRUE;
// some more code
}

بعد ذلك ، لدي قراءة تتم في موضوع آخر (يحتمل في نفس الوقت):

Terminate()
{
// some code
if( m_bIsTerminated )
{
m_dwThreadId = 0;
m_hThread = NULL;
m_evExit.SetEvent();
return;
}
// even more code
}

ما هو أفضل حل لحل حالة السباق هذه؟ هل الأقسام الحرجة هي الطريق للذهاب أم أن استخدام interlockedexchangeadd () أكثر فائدة؟

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

المحلول

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

لسيناريو الخاص بك ، يمكنك بالتأكيد استخدام وظيفة متشابكة ...- لكنني سأستخدم حدثًا (CreateEvent ، setevent ، waitforsingleobject) ، ربما لأنني غالبًا في السيناريو الخاص بك).

UPD: قد يعمل استخدام المتقلبة للمتغير ، ومع ذلك لا ينصح به ، راجع: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2016.html و http://www-949.ibm.com/software/rational/cafe/blogs/ccpp-paralled-multicore/tags/c٪2b٪2b0x على سبيل المثال.

إذا كنت تريد أن تكون محمولًا ، ألق نظرة على Boost :: Thread.

نصائح أخرى

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

تستخدم عائلة InterLockEdxxx من الوظائف أوامر INTEL CPU الذرية 3-OPERand (XADD و CMPXCNG). لذلك هم أرخص بكثير من القسم الحرج. والطويلة التي تريدها لتخصيص مؤشرات الترابط هي interlockedCompareexChange ().

UPD: وعلامة المتغير على أنها متقلبة.

تأكد من تمييز m_bisterminated على أنه متقلب ، ويجب أن تكون على ما يرام. على الرغم من أنه يبدو غريباً بالنسبة لي أنك ستتم إنهاء المزيد من التعليمات البرمجية بعد الإعداد "إلى صواب. ماذا يشير هذا المتغير بالضبط؟

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

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