ما هي بعض الطرق "الجيدة" لاستخدام longjmp/setjmp لمعالجة الأخطاء في لغة C؟

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

سؤال

لا بد لي من استخدام لغة C لمشروع واحد وأفكر في استخدامها longjmp/setjmp لمعالجة الأخطاء لأنني أعتقد أنه سيكون من الأسهل بكثير التعامل مع الخطأ في مكان مركزي واحد بدلاً من إرجاع الرموز.وسأكون ممتنًا إذا كانت هناك بعض الأدلة حول كيفية القيام بذلك.

أنا مهتم بشكل خاص بإجراء عملية تنظيف الموارد بشكل صحيح في حالة حدوث أي خطأ من هذا القبيل.

وأيضًا كيف أتعامل مع الأخطاء التي تؤدي إلى استخدام برامج متعددة الخيوط لها؟

والأفضل من ذلك، هل توجد مكتبة C موجودة بالفعل لمعالجة الأخطاء/الاستثناءات؟

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

المحلول

وإلقاء نظرة على هذا المثال / تعليمي:
http://www.di.unipi.it/~nids/docs/longjump_try_trow_catch هتمل

نصائح أخرى

إذا كنت قلقا حول تنظيف الموارد، يجب أن نتساءل بجدية في ما إذا longjmp () وsetjmp () هي فكرة جيدة.

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

نفذت سيمبيان ذلك Leave آلية من حيث longjmp() وهذا بمثابة جولة جيدة عبر كل الأشياء التي تحتاج إلى القيام بها.

لدى Symbian "مكدس تنظيف" عالمي يمكنك من خلاله دفع الأشياء التي تريد تنظيفها وإزالتها في حالة حدوث قفزة.هذا هو البديل اليدوي لفك المكدس التلقائي الذي يقوم به مترجم C++ عند طرح استثناء C++.

كان لدى Symbian "أدوات فخ" يمكن القفز إليها؛يمكن أن تكون متداخلة.

(أعادت شركة Symbian تنفيذها مؤخرًا فيما يتعلق باستثناءات C++، لكن الواجهة ظلت دون تغيير).

معًا، أعتقد أن الاستثناءات المناسبة لـ C++ أقل عرضة لأخطاء الترميز وأسرع بكثير من تدوير مكافئ C الخاص بك.

(تعتبر برامج التحويل البرمجي الحديثة لـ C++ جيدة جدًا في استثناءات "الحمل الزائد الصفري" عندما لا يتم طرحها، على سبيل المثال؛ longjmp() يجب أن يخزن حالة جميع السجلات، وذلك حتى عندما لا يتم إجراء القفزة لاحقًا، لذلك لا يمكن أبدًا أن تكون بنفس سرعة الاستثناءات.)

إن استخدام C++ باعتباره لغة C أفضل، حيث تعتمد فقط الاستثناءات وRAII، سيكون طريقًا جيدًا يجب استخدامه longjmp() لأن الاستثناء يكون مضاهاة مغرية لك.

ولقد وجدت فقط من أي وقت مضى <م> واحدة استخدام لsetjmp()/longjmp() وأنه لم يكن له علاقة معالجة الأخطاء.

وهناك فعلا حاجة لاستخدامه لهذا لأنه يمكن أن يكون دائما ريفاكتوريد إلى شيء أسهل لمتابعة. استخدام setjmp()/longjmp() هي مشابهة جدا لgoto في أنه يمكن أن يساء استخدامها بسهولة. أي شيء يجعل الشفرة أقل قابلية للقراءة هو فكرة سيئة بشكل عام. لاحظ أن لا أقول انهم سيئة بطبيعتها، أن مجرد أنها يمكن أن تؤدي إلى رمز سيئة أسهل من البدائل.

وFWIW، كان مكان واحد كانوا لا تقدر بثمن مشروع فعلت في الأيام الأولى للصناعة (MS-DOS إطار 6 مرة). تمكنت من تشكيل مكتبة متعدد خيوط التعاونية باستخدام توربو C التي تستخدم هذه الوظائف في وظيفة yield() للتبديل المهام.

وأنا واثق جدا لم أتطرق لها (أو كان ضرورة) منذ تلك الأيام.

ويستثنى من ذلك حتى الآن آلية أفضل العامة، ولكن في الأيام المظلمة العميقة C الماضي، كتبت محاكي المعالج الذي اشتمل على قذيفة الأوامر. قذيفة تستخدم لsetjmp / longjmp للتعامل مع المقاطعة (أي المعالج يعمل بنظام التشغيل وضغط المستخدم على كسر / CTRL-ج، وSIGINT الفخاخ رمز وlongjmps إلى شل).

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

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

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

ويفعلون ذلك في سياق متعددة الخيوط البرمجة؟ أنا متأكد من أن هذا لم يكن من المستحيل، ولكن ووه: الخروج عائلتك حزمة من الأسبرين الآن. انها على الارجح الحكمة للحفاظ على أزواج setjmp / longjmp أقرب معا ممكن. ما دام setjmp مطابقة / الزوج longjmp هم في نفس الموضوع، وأتوقع أنك سوف تكون على ما يرام، ولكن ... كن حذرا هناك.

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