سؤال

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

فهل يعرف أحد أي أدوات أو تقنيات من شأنها أن تساعد في تحليل وتوثيق جميع التفاعلات بين المواضيع؟FWIW، قاعدة التعليمات البرمجية هي C++ على Linux، ولكنني سأكون مهتمًا بمعرفة المزيد عن الأدوات المخصصة للبيئات الأخرى.


تحديث

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


أنظر أيضا تصحيح أخطاء التطبيقات متعددة الخيوط

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

المحلول

استثمر في نسخة من Intel فتون وأدوات التنميط الموضوع.سوف يمنحك نظامًا وعرضًا على مستوى المصدر لسلوك الخيط.من المؤكد أنها لن تقوم بتوثيق الأمر تلقائيًا، ولكن يجب أن تكون مساعدة حقيقية على الأقل في تصور ما يحدث في ظروف مختلفة.

أعتقد أن هناك نسخة تجريبية يمكنك تنزيلها، لذا قد يكون من المفيد تجربتها.لقد استخدمت إصدار Windows فقط، ولكن بالنظر إلى صفحة ويب VTune، فإنها تحتوي أيضًا على إصدار Linux.

نصائح أخرى

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

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

بالنظر إلى قائمة كائنات المزامنة التي يتم الاحتفاظ بها وفكرة تقريبية عن الحالة التي تحميها، قم بتعيين أمر قفل (على سبيل المثال، يجب دائمًا أخذ كائن المزامنة A قبل كائن المزامنة B).حاول فرض ذلك في الكود.

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

لن يكون الأمر سهلاً ولكني أؤيد تبسيط الكود على حساب التزامن للتعامل مع المشكلة.

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

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

StEAM هو مدقق نموذجي لـ C++.يكتشف حالات الجمود وأخطاء التجزئة والمتغيرات خارج النطاق والحلقات غير المنتهية.

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

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

في Java، لديك خيارات مثل FindBugs (لتحليل الرمز الثانوي الثابت) للعثور على أنواع معينة من المزامنة غير المتناسقة، أو العديد من أدوات تحليل الخيوط الديناميكية من شركات مثل Coverity، وJProbe، وOptimizeIt، وما إلى ذلك.

ألا تستطيع UML مساعدتك هنا؟

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

سيُظهر هذا أيضًا "كائنات البيانات" التي تمت مشاركتها والكائنات الخاصة بسلسلة المحادثات.

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

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

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