سؤال

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

هل هناك طريقة للقيام بـ pthread_join غير محظور؟سيكون نوعًا ما من الانضمام المحدد بوقت جيدًا أيضًا.

شيء من هذا القبيل:

foreach thread do
  nb_pthread_join();
    if still running
      pthread_cancel();

يمكنني التفكير في المزيد من الحالات التي يكون فيها الانضمام غير المحظور مفيدًا.

كما يبدو أنه لا توجد مثل هذه الوظيفة، فقد قمت بالفعل بترميز الحل البديل، لكنه ليس بهذه البساطة كما أريد.

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

المحلول

كما أشار آخرون، لا يوجد pthread_join غير محظور متاح في مكتبات pthread القياسية.

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

int killed_threads = 0;
for(i = 0; i < num_threads; i++) {
   int return = pthread_cancel(threads[i]);
   if(return != ESRCH)
      killed_threads++;
}
if(killed_threads)
    printf("%d threads did not shutdown properly\n", killed_threads)
else
    printf("All threads exited successfully");

لا حرج في استدعاء pthread_cancel على جميع سلاسل الرسائل الخاصة بك (سواء تم إنهاؤها أم لا) لذا فإن الاتصال بذلك لجميع سلاسل الرسائل الخاصة بك لن يتم حظره وسيضمن خروج الخيط (سواء كان نظيفًا أم لا).

يجب أن يكون ذلك بمثابة حل بديل "بسيط".

نصائح أخرى

إذا كنت تقوم بتشغيل تطبيقك على Linux، فقد تكون مهتمًا بمعرفة ما يلي:

int pthread_tryjoin_np(pthread_t thread, void **retval);

int pthread_timedjoin_np(pthread_t thread, void **retval,
                                const struct timespec *abstime);

كن حذرًا، كما تشير اللاحقة، فإن "np" تعني "غير محمول".إنها ليست امتدادات POSIX القياسية، ولكنها مفيدة بالرغم من ذلك.

رابط إلى صفحة الرجل

تعد آلية "pthread_join" وسيلة سهلة الاستخدام إذا حدث ما تريده بالضبط.إنه لا يفعل أي شيء لا يمكنك فعله بنفسك، وعندما لا يكون ما تريده بالضبط، قم ببرمجة ما تريده بالضبط.

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

ابدأ بتغيير تفكيرك.ليس الخيط هو الذي يعلق، بل ما كان يفعله الخيط هو الذي يعلق.

إذا كنت تقوم بالتطوير لـ QNX، فيمكنك استخدام وظيفة pthread_timedjoin().

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

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

لست متأكدًا مما تقصده بالضبط، ولكني أفترض أن ما تحتاجه حقًا هو آلية الانتظار والإخطار.

باختصار، إليك كيفية العمل:أنت تنتظر الشرط للوفاء بمهلة.سينتهي انتظارك إذا:

  • تحدث المهلة، أو
  • إذا تم استيفاء الشرط.

يمكنك الحصول على هذا في حلقة وإضافة المزيد من الذكاء إلى المنطق الخاص بك.أفضل مورد وجدته فيما يتعلق بـ Pthreads هو هذا البرنامج التعليمي:برمجة خيوط POSIX (https://computing.llnl.gov/tutorials/pthreads/).

أنا أيضًا مندهش جدًا عندما أرى أنه لا توجد واجهة برمجة تطبيقات للانضمام المحدد بوقت في Pthreads.

لا يوجد توقيت pthread_join, ولكن إذا كنت تنتظر حظر موضوع آخر بشروط، فيمكنك استخدام Timed pthread_cond_timed_wait بدلاً من pthread_cond_wait

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

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