سؤال

ما هي إيجابيات / سلبيات استخدام pthread_cond_wait أو باستخدام إشارة ?أنا في انتظار تغيير الحالة مثل هذا :

pthread_mutex_lock(&cam->video_lock);
while(cam->status == WAIT_DISPLAY) {
    pthread_cond_wait(&cam->video_cond, &cam->video_lock);
}
pthread_mutex_unlock(&cam->video_lock);

تستخدم بشكل صحيح initialised إشارة أعتقد أنني يمكن أن تفعل ذلك من هذا القبيل :

while(cam->status == WAIT_DISPLAY) {
    sem_wait(&some_semaphore);
}

ما هي إيجابيات وسلبيات كل طريقة ؟

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

المحلول

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

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

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

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

متغيرات حالة الهروب هذه المشكلة لأن الدعوة cond_wait تلقائيا تطلق مزامنة ، تخليصه للاستخدام من قبل الآخرين.مزامنة هو استعاد قبل cond_wait العوائد.

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

نصائح أخرى

الشرطية تمكنك من القيام ببعض الأشياء التي الإشارات لا.

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

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

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

2 مقتطف هو مفعم بالحيوية, لا تفعل ذلك.

إجابات أخرى لطيفة مناقشة المزايا النسبية;أنا أضيف أن pthread_cond_broadcast هو ميزة واضحة من حالة المتغيرات.

أبعد من ذلك, أنا فقط أكثر تستخدم في حالة المتغيرات ، كما هي ما تستخدمها في جافا ، حتى لأنها تساعدك على تجنب سباقات عند التحقق المشتركة الأعلام.

في الواقع ، في 2 مقتطف لم يكن لديك أي قفل حماية قراءة كام->حالة, حتى يتم الوصول إليه من خلال البيانات السباق.معظم المنصات سوف تمكنك من الحصول على بعيدا مع أن في هذا المثال بالتحديد ، ولكن هذا غير معرفة دلالات ، POSIX و الذاكرة النموذج التالي C/C++ المعايير.

في الواقع, سباق حقيقي الشرط هو ممكن إذا كان مؤشر ترابط آخر تخصص جديد كام هيكل الكتابة كام.في انتظار الموضوع قد نرى التحديث إلى 'كاميرا' المؤشر دون رؤية تهيئة كام->الحالة.في الواقع, 2 مقتطف يسأل عن المتاعب في هذه الحالة و في العامة.

http://www.hpl.hp.com/personal/Hans_Boehm/c++mm/

في الثاني مقتطف من أنك تحصل على قفل العديد من المرات ، لم إطلاقه.

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

وإلا إذا كانت الدولة هي معقدة أجزاء مختلفة من رمز الانتظار في ظروف مختلفة من نفس المتغير (على سبيل المثال, هنا تريد x<10;هناك تريد y>x), استخدام cond_wait.

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