Window.pipedriveLeadboosterConfig = { القاعدة: 'leadbooster-chat.pipedrive.com', companyId: 11580370, playbookUuid: '22236db1-6d50-40c4-b48f-8b11262155be', الإصدار: 2, } ؛(الدالة () { var w = نافذة إذا كان (w.LeadBooster) { console.warn('LeadBooster موجود بالفعل') } وإلا { { w.LeadBooster = { q: [], على: دالة (ن، ح) { { هذا.q.push({ t: 'o'، n: n، n: n، h: h }) }, الزناد: الدالة (n) { هذا.q.push({ t: 't'، n: n: n }) }, } } })() التفرع والترابط في روبي - The Codest
The Codest
  • نبذة عنا
  • الخدمات
    • تطوير البرمجيات
      • تطوير الواجهة الأمامية
      • تطوير الواجهة الخلفية
    • Staff Augmentation
      • مطورو الواجهة الأمامية
      • مطورو الواجهة الخلفية
      • مهندسو البيانات
      • مهندسو السحابة
      • مهندسو ضمان الجودة
      • أخرى
    • استشاري
      • التدقيق والاستشارات
  • الصناعات
    • التكنولوجيا المالية والمصرفية
    • E-commerce
    • أدتك
    • التكنولوجيا الصحية
    • التصنيع
    • الخدمات اللوجستية
    • السيارات
    • إنترنت الأشياء
  • القيمة مقابل
    • CEO
    • CTO
    • مدير التوصيل
  • فريقنا
  • دراسات الحالة
  • اعرف كيف
    • المدونة
    • اللقاءات
    • ندوات عبر الإنترنت
    • الموارد
الوظائف تواصل معنا
  • نبذة عنا
  • الخدمات
    • تطوير البرمجيات
      • تطوير الواجهة الأمامية
      • تطوير الواجهة الخلفية
    • Staff Augmentation
      • مطورو الواجهة الأمامية
      • مطورو الواجهة الخلفية
      • مهندسو البيانات
      • مهندسو السحابة
      • مهندسو ضمان الجودة
      • أخرى
    • استشاري
      • التدقيق والاستشارات
  • القيمة مقابل
    • CEO
    • CTO
    • مدير التوصيل
  • فريقنا
  • دراسات الحالة
  • اعرف كيف
    • المدونة
    • اللقاءات
    • ندوات عبر الإنترنت
    • الموارد
الوظائف تواصل معنا
السهم الخلفي العودة إلى الوراء
2016-10-06
تطوير البرمجيات

التفرع والترابط في روبي

ماريك جيرلاتش

كما تعلمون على الأرجح، لدى روبي عدد قليل من التطبيقات، مثل MRI و JRuby و Rubinius و Opal و RubyMotion وغيرها، وقد يستخدم كل منها نمطًا مختلفًا لتنفيذ التعليمات البرمجية. ستركز هذه المقالة على الثلاثة الأولى منها ومقارنة MRI

كما تعلمون على الأرجح، لدى روبي عدد قليل من التطبيقات، مثل MRI و JRuby و Rubinius و Opal و RubyMotion وغيرها، وقد يستخدم كل منها نمطًا مختلفًا من الكود التنفيذ. ستركز هذه المقالة على الثلاثة الأولى منها ومقارنة MRI (التطبيق الأكثر شيوعًا حاليًا) مع JRuby و Rubinius من خلال تشغيل بعض نماذج البرامج النصية التي من المفترض أن تقيّم مدى ملاءمة التفرّع والترابط في مواقف مختلفة، مثل معالجة الخوارزميات التي تحتاج إلى وحدة معالجة مركزية مكثفة، ونسخ الملفات وما إلى ذلك، قبل البدء في "التعلم بالممارسة"، تحتاج إلى مراجعة بعض المصطلحات الأساسية.

شوكة

  • عملية فرعية جديدة (نسخة من العملية الأم)
  • لديه معرّف عملية جديد (PID)
  • لها ذاكرة منفصلة*
  • يتواصل مع الآخرين عبر قنوات الاتصال بين العمليات (IPC) مثل قوائم انتظار الرسائل والملفات والمآخذ وما إلى ذلك.
  • موجودة حتى عند انتهاء العملية الأم
  • هو استدعاء POSIX - يعمل بشكل رئيسي على منصات يونكس

الخيط

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

هناك الكثير من الأدوات التي تستخدم الشوكات والخيوط، والتي يتم استخدامها بشكل يومي، على سبيل المثال يونيكورن (شوكات) وبوما (خيوط) على مستوى خوادم التطبيقات، وريسكيو (شوكات) وسيديكيك (خيوط) على مستوى وظائف الخلفية، إلخ.

يعرض الجدول التالي دعم التفرّع والترابط في تطبيقات روبي الرئيسية.

تنفيذ روبيالتفرعالخيوط
التصوير بالرنين المغناطيسينعمنعم (محدودة ب GIL**)
جي روبي–نعم
روبينيوسنعمنعم

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

التقرير المحدد لعام 2020

يعرض الجدول التالي دعم التوازي والتزامن.

تنفيذ روبيالتوازي (عبر الشوكات)التوازي (عبر الخيوط)التزامن
التصوير بالرنين المغناطيسينعملا يوجدنعم
جي روبي–نعمنعم
روبينيوسنعمنعم (منذ الإصدار 2.X)نعم

هذه هي نهاية النظرية - دعونا نرى ذلك على أرض الواقع!

  • وجود ذاكرة منفصلة لا يتسبب بالضرورة في استهلاك نفس المقدار الذي تستهلكه العملية الأم. هناك بعض تقنيات تحسين الذاكرة. إحدى هذه التقنيات هي النسخ عند الكتابة (CoW)، والتي تسمح للعملية الأم بمشاركة الذاكرة المخصصة مع العملية الفرعية دون نسخها. مع CoW تكون هناك حاجة إلى ذاكرة إضافية فقط في حالة تعديل الذاكرة المشتركة من قبل عملية فرعية. في سياق روبي، ليس كل تطبيق متوافق مع CoW، على سبيل المثال يدعمه MRI بشكل كامل منذ الإصدار 2.X. قبل هذا الإصدار كانت كل عملية شوكة تستهلك نفس القدر من الذاكرة التي تستهلكها العملية الأم.
  • واحدة من أكبر مزايا/عيوب التصوير بالرنين المغناطيسي (شطب البديل غير المناسب) هو استخدام GIL (قفل المترجم العالمي). باختصار، هذه الآلية مسؤولة عن مزامنة تنفيذ سلاسل الرسائل، مما يعني أنه يمكن تنفيذ سلسلة رسائل واحدة فقط في كل مرة. لكن انتظر... هل هذا يعني أنه لا فائدة من استخدام الخيوط في MRI على الإطلاق؟ الجواب يأتي مع فهم الأجزاء الداخلية لـ GIL... أو على الأقل إلقاء نظرة على نماذج الشيفرة في هذه المقالة.

حالة الاختبار

من أجل تقديم كيفية عمل التفرّع والترابط في تطبيقات روبي، أنشأتُ فصلاً بسيطًا يسمى الاختبار وبعض الفئات الأخرى المتوارثة منه. كل صنف لديه مهمة مختلفة للمعالجة. بشكل افتراضي، تعمل كل مهمة أربع مرات في حلقة. أيضًا، تعمل كل مهمة مقابل ثلاثة أنواع من تنفيذ التعليمات البرمجية: متسلسلة، مع شوكات، ومع خيوط. بالإضافة إلى ذلك, Benchmark.bmbm تشغيل كتلة الكود مرتين - المرة الأولى من أجل تشغيل بيئة وقت التشغيل وتشغيلها، والمرة الثانية من أجل القياس. تم الحصول على جميع النتائج المعروضة في هذه المقالة في التشغيل الثاني. بالطبع، حتى ب م ب م م طريقة لا تضمن العزل التام، ولكن الاختلافات بين عمليات تشغيل الشيفرة المتعددة ضئيلة.

تتطلب "معيار"

فئة الاختبار
  المبلغ = 4

  تعريف تشغيل
    Benchmark.bmbm do |b|
      b.report("متسلسل") { متسلسل }
      b.report("التفرع") { متسلسل }
      b.report("الترابط") { مترابطة } { مترابطة }
    نهاية
  النهاية

  خاص

  تعريف متسلسل
    AMOUNT.times { تنفيذ }
  نهاية

  ديف فوركينج
    AMOUNT.times do
      شوكة تفعل
        تنفيذ
      إنهاء
    النهاية

    Process.waitall
  إنقاذ NotImplementedError => e
    # طريقة الشوكة غير متوفرة في JRuby
    يضع e
  إنهاء

  تعريف الترابط
    الخيوط = []

    AMOUNT.times do
      الخيوط << Thread.new do
        تنفيذ
      النهاية
    النهاية

    المواضيع.map(&:join)
  النهاية

  ديف تنفيذ
    رفع "غير منفذة"
  إنهاء
النهاية
اختبار التحميل

تشغيل العمليات الحسابية في حلقة لتوليد حمل كبير على وحدة المعالجة المركزية.

صنف LoadTest <اختبار
  تعريف الأداء
    1000.times { 1000.times { 2**3**4 } }
  نهاية
النهاية

لنقم بتشغيله...

LoadTest.new.run

...وتحقق من النتائج

التصوير بالرنين المغناطيسيجي روبيروبينيوس
متتابعة1.8629282.0890001.918873
التفرع0.945018–1.178322
الخيوط1.9139821.1070001.213315

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

في هذا المثال، يحقق التفرع في هذا المثال مكسبًا كبيرًا في الأداء (تعمل الشيفرة البرمجية أسرع بمرتين تقريبًا).

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

لا يعطينا هذا المثال إجابة عن السؤال حول معنى خيوط الاستخدام في التصوير بالرنين المغناطيسي. دعونا نرى مثالاً آخر.

اختبار الغفوة

تشغيل طريقة السكون.

صنف SnoozeTest <اختبار
  تعريف الأداء
    النوم 1
  النهاية
النهاية

فيما يلي النتائج

التصوير بالرنين المغناطيسيجي روبيروبينيوس
متتابعة4.0046204.0060004.003186
التفرع1.022066–1.028381
الخيوط1.0015481.0040001.003642

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

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

باطل ثابت
سكون أصلي(rb_sleep(rb_thread_t_t *th، هيكل الفاصل الزمني *timeout_tv)
{
  ...

  gvl_unlock_begin();
  {
    // القيام ببعض الأشياء هنا
  }
  gvl_unlock_beend();

  thread_debug("native_sleep donen");
 }

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

يصبح الوضع واضحًا، ولكن النوم طريقة نادراً ما تكون مفيدة. نحن بحاجة إلى المزيد من الأمثلة الواقعية.

اختبار تنزيل الملفات

تشغيل عملية تقوم بتنزيل ملف وحفظه.

تتطلب "نت/إتش تي بي تي"

صنف DownloadFileTest <اختبار
  تعريف الأداء
    Net::HTTP.get("upload.wikimedia.org", "/wikipedia/commons/thumb/7/73/Ruby_logo.svg/2000px-Ruby_logo.svg.png")
  النهاية
النهاية

ليست هناك حاجة للتعليق على النتائج التالية. فهي تشبه إلى حد كبير نتائج المثال أعلاه.

1.003642جي روبيروبينيوس
متتابعة0.3279800.3340000.329353
التفرع0.104766–0.121054
الخيوط0.0857890.0940000.088490

مثال جيد آخر يمكن أن يكون عملية نسخ الملفات أو أي عملية إدخال/إخراج أخرى.

الاستنتاجات

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

مقالات ذات صلة

تطوير البرمجيات

إنشاء تطبيقات ويب مستقبلية: رؤى من فريق خبراء The Codest

اكتشف كيف تتفوق شركة The Codest في إنشاء تطبيقات ويب تفاعلية قابلة للتطوير باستخدام أحدث التقنيات، وتقديم تجارب مستخدم سلسة عبر جميع المنصات. اكتشف كيف تقود خبرتنا التحول الرقمي والأعمال التجارية...

ذا كوديست
تطوير البرمجيات

أفضل 10 شركات لتطوير البرمجيات في لاتفيا

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

thecodest
الحلول المؤسسية وحلول التوسعة

أساسيات تطوير برمجيات جافا: دليل للاستعانة بمصادر خارجية بنجاح

استكشف هذا الدليل الأساسي حول تطوير برمجيات جافا outsourcing بنجاح لتعزيز الكفاءة والوصول إلى الخبرة وتحقيق نجاح المشروع باستخدام The Codest.

thecodest
تطوير البرمجيات

الدليل الشامل للاستعانة بمصادر خارجية في بولندا

إن الطفرة في outsourcing في بولندا مدفوعة بالتقدم الاقتصادي والتعليمي والتكنولوجي، مما يعزز نمو تكنولوجيا المعلومات والمناخ الملائم للأعمال.

ذا كوديست
الحلول المؤسسية وحلول التوسعة

الدليل الكامل لأدوات وتقنيات تدقيق تكنولوجيا المعلومات

تضمن عمليات تدقيق تكنولوجيا المعلومات وجود أنظمة آمنة وفعالة ومتوافقة. تعرف على المزيد حول أهميتها من خلال قراءة المقال كاملاً.

The Codest
ياكوب جاكوب جاكوبوفيتش CTO وشريك مؤسس CTO

اشترك في قاعدة معارفنا وابقَ على اطلاع على آخر المستجدات في قطاع تكنولوجيا المعلومات.

    نبذة عنا

    The Codest - شركة دولية لتطوير البرمجيات لها مراكز تقنية في بولندا.

    المملكة المتحدة - المقر الرئيسي

    • المكتب 303 ب، 182-184 شارع هاي ستريت نورث E6 2JA
      لندن، إنجلترا

    بولندا - مراكز التكنولوجيا المحلية

    • مجمع مكاتب فابريتشنا المكتبي، أليجا
      بوكوجو 18، 31-564 كراكوف
    • سفارة الأدمغة، كونستروكتورسكا
      11, 02-673 02-673 وارسو، بولندا

      The Codest

    • الصفحة الرئيسية
    • نبذة عنا
    • الخدمات
    • دراسات الحالة
    • اعرف كيف
    • الوظائف
    • القاموس

      الخدمات

    • استشاري
    • تطوير البرمجيات
    • تطوير الواجهة الخلفية
    • تطوير الواجهة الأمامية
    • Staff Augmentation
    • مطورو الواجهة الخلفية
    • مهندسو السحابة
    • مهندسو البيانات
    • أخرى
    • مهندسو ضمان الجودة

      الموارد

    • حقائق وأساطير حول التعاون مع شريك خارجي لتطوير البرمجيات
    • من الولايات المتحدة الأمريكية إلى أوروبا: لماذا تقرر الشركات الأمريكية الناشئة الانتقال إلى أوروبا؟
    • مقارنة مراكز تطوير التكنولوجيا في الخارج: تك أوفشور أوروبا (بولندا)، آسيان (الفلبين)، أوراسيا (تركيا)
    • ما هي أهم التحديات التي تواجه CTOs ومديري تكنولوجيا المعلومات؟
    • The Codest
    • The Codest
    • The Codest
    • Privacy policy
    • شروط استخدام الموقع الإلكتروني

    جميع الحقوق محفوظة © 2025 بواسطة The Codest. جميع الحقوق محفوظة.

    arArabic
    en_USEnglish de_DEGerman sv_SESwedish da_DKDanish nb_NONorwegian fiFinnish fr_FRFrench pl_PLPolish it_ITItalian jaJapanese ko_KRKorean es_ESSpanish nl_NLDutch etEstonian elGreek arArabic