رفع استثناءات غير معلقة في مؤشر ترابط في الخيط الرئيسي؟ [مكرر

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

سؤال

هذا السؤال لديه بالفعل إجابة هنا:

هناك بعض الأسئلة المماثلة، ولكن لا يوجد أي تعرض الإجابة التي أحتاجها.

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

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

ما هي أفضل طريقة للذهاب حول هذا الموضوع؟

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

المحلول

كتبت عن إعادة إلقاء استثناءات في بيثون, ، بما في ذلك شيء مثل هذا مثل هذا مثال.

على خيط العامل الخاص بك تقوم بهذا (Python 2.x، انظر أدناه للحصول على إصدار Python 3.x):

try:
    self.result = self.do_something_dangerous()
except Exception, e:
    import sys
    self.exc_info = sys.exc_info()

وعلى موضوعك الرئيسي الذي تقوم بهذا:

if self.exc_info:
    raise self.exc_info[1], None, self.exc_info[2]
return self.result

سيظهر الاستثناء في الخيط الرئيسي كما لو كان قد أثيرت في مؤشر ترابط العمال.

بيثون 3.x:

try:
    self.result = self.do_something_dangerous()
except Exception as e:
    import sys
    self.exc_info = sys.exc_info()

وعلى الخيط الرئيسي الخاص بك:

if self.exc_info:
    raise self.exc_info[1].with_traceback(self.exc_info[2])
return self.result

نصائح أخرى

الاستثناء الوحيد الذي يمكن أن يرفع مؤشر ترابط ثانوي بشكل موثوق في الخيط الرئيسي هو KeyboardInterrupt: الطريقة التي يفعلها الموضوع الثانوي عن طريق استدعاء الوظيفة thread.interrupt_main(). وبعد لا توجد وسيلة لربط معلومات إضافية (حول سبب الاستثناء) مع كائن الاستثناء الذي يتم رفعه - هذا الأخير دائما سهل KeyboardInterrupt. وبعد لذلك، تحتاج إلى تخفيف هذه المعلومات بعيدا في مكان آخر، على سبيل المثال على مثيل مخصص من Queue.queue. - قد تتضمن هذه المعلومات النتائج التي يمكن أن تحصل عليها الموضوع الثانوي sys.exc_info(), وأي شيء آخر تجده مفيدا بالطبع.

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

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

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