قفل ثلاثي فحص؟
-
24-09-2019 - |
سؤال
لذلك في الوقت نفسه ، نعلم أن القفل المزدوج كما هو لا يعمل في C ++ ، على الأقل ليس بطريقة محمولة.
لقد أدركت للتو أن لديّ تطبيق هش في Quadtree كسول أستخدمه لتتبع شعاع التضاريس. لذلك حاولت إيجاد طريقة لاستخدام التهيئة البطيئة بطريقة آمنة ، حيث لا أرغب في استخدام الذاكرة الرباعية وإعادة ترتيب أجزاء كبيرة من الخوارزميات المنفذة.
هذا اجتياز مستوحى من النمط في الصفحة 12 من C ++ ومخاطر القفل المزدوج, ، لكن يحاول القيام بذلك أرخص:
(pseudo code!)
struct Foo {
bool childCreated[4];
Mutex mutex[4];
Foo child[4];
void traverse (...) {
...
if (!childCreated[c]) {
// get updated view
#pragma flush childCreated[c]
if (!childCreated[c]) {
ScopedLock sl (mutex[c]);
if (!childCreated[c]) {
create (c);
#pragma flush childCreated[c]
childCreated[c] = true;
}
}
}
}
}
يفترض أن #pragma flush
سيكون بمثابة نقطة تسلسل صلبة حيث لن يُسمح للمترجمين والمعالجات بإعادة ترتيب العمليات عبرهم.
ما هي المشاكل التي تراها؟
تعديل: الإصدار 2 ، في محاولة لمراعاة إجابة VLADS (تقديم Flush الثالث):
(pseudo code!)
struct Foo {
bool childCreated[4];
Mutex mutex[4];
Foo child[4];
void traverse (...) {
...
if (!childCreated[c]) {
// get updated view
#pragma flush childCreated[c]
if (!childCreated[c]) {
ScopedLock sl (mutex[c]);
#pragma flush childCreated[c]
if (!childCreated[c]) {
create (c);
#pragma flush childCreated[c]
childCreated[c] = true;
}
}
}
}
}
تعديل: الإصدار 3 ، أجد بطريقة ما معادلة إلى حد ما للإصدار 2 ، لأنني لا أستخدم الطفل نفسه بل علامة بدائية للتحقق من الصلاحية ، والاعتماد بشكل أساسي على حاجز الذاكرة بين إنشاء طفل والكتابة على هذا العلم.
(pseudo code!)
struct Foo {
bool childCreated[4];
Mutex mutex[4];
Foo child[4];
void traverse (...) {
...
if (!childCreated[c]) {
ScopedLock sl (mutex[c]);
#pragma flush childCreated[c]
if (!childCreated[c]) {
create (c);
#pragma flush childCreated[c]
childCreated[c] = true;
}
}
}
}
المحلول
يبدو أن نمطك غير صحيح. النظر في الحالة عندما يتم تنفيذ الموضوع رقم 1 حتى بعد الأول #pragma flush
. ثم يتحول عنصر التحكم إلى الخيط رقم 2 ، والذي يمتد ويخلق أ c
, ، يتم إعادة السيطرة قبل الثانية مباشرة #pragma flush
. الآن يستيقظ الخيط الأول ، ويخلق الطفل من جديد.
تحرير: آسف ، خطأ: لن يكون من الممكن أخذ القفل.
تحرير 2: لا ، لا تزال صحيحة ، لأن القيمة لن يتم مسحها في الموضوع رقم 1