كيف أتجنب انتهاكات السلاسل المتقاطعة في امتداد روبي؟

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

سؤال

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

[BUG] cross-thread violation in rb_thread_schedule()

يعني الإدخال / الإخراج غير المتزامن أن امتداد C الخاص بي سيحتاج إلى تسليم رسائل إلى روبي من سلاسل رسائل متعددة (وليس مؤشر ترابط المترجم الرئيسي).كيف يمكنني تجنب انتهاكات سلامة الخيط أثناء هذه العملية؟

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

المحلول

بالنسبة لـ Ruby 1.8.x، الطريقة الوحيدة لتجنب الخطأ هي الطريقة الواضحة - فقط استدعاء Ruby/C API من سلسلة المترجم الرئيسي.أعتقد أن هذا ينطبق على Ruby 1.9.x أيضًا، لكنني لم أعمل معه ولا أعرف كيف يمكن أن يغير دعم الخيط الأصلي الأشياء.بدلاً من استدعاء عدة سلاسل رسائل أصلية مباشرة لواجهة برمجة التطبيقات (API)، تحتاج إلى استخدام نمط المنتج/المستهلك لتسليم الطلبات من سلاسل الرسائل الأصلية الثانوية إلى التعليمات البرمجية الخاصة بك في سلسلة رسائل المترجم الرئيسي.ومن الأفضل القيام بذلك مع عدم حظر خيوط روبي الخضراء الأخرى دون داع.إذا نظرت إلى تنفيذ روبي، فإن جدولة الخيط الأخضر روبي هو أمر أساسي select() حلقة.وهذا يشير إلى الهيكل العام التالي:

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

يرى rb_io_sysread() (بداية شئ IO#sysread) لما قد يكون أبسط وظيفة نظيفة لاستخدام الإدخال والإخراج في قاعدة كود روبي.

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