سؤال

أعرف عن الخيوط "التعاونية" لاستخدام الياقوت المواضيع الخضراء.كيف يمكنني إنشاء سلاسل رسائل حقيقية "على مستوى نظام التشغيل" في تطبيقي للاستفادة من مراكز وحدة المعالجة المركزية المتعددة للمعالجة؟

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

المحلول

تم التحديث باستخدام تعليق Jörg في سبتمبر 2011

يبدو أنك تخلط بين الاثنين جداً أشياء مختلفة هنا:لغة برمجة Ruby ونموذج الخيوط المحدد لتنفيذ محدد للغة برمجة Ruby.يوجد حاليًا حوالي 11 تطبيقًا مختلفًا للغة برمجة Ruby ، ​​مع جداً نماذج خيوط مختلفة وفريدة من نوعها.

(لسوء الحظ ، هناك اثنان فقط من هذه التطبيقات الـ 11 جاهزة فعليًا للاستخدام الإنتاجي ، ولكن بحلول نهاية العام ، من المحتمل أن يصل هذا الرقم إلى أربعة أو خمسة.) (تحديث:إنها الآن 5:MRI، JRuby، YARV (المترجم لـ Ruby 1.9)، Rubinius وIronRuby).

  1. لا يحتوي التنفيذ الأول على اسم ، مما يجعله محرجًا تمامًا للإشارة إليه وهو مزعج ومربك حقًا.يشار إلى غالبًا باسم "Ruby" ، وهو أكثر إزعاجًا ومربكًا من عدم وجود اسم ، لأنه يؤدي إلى ارتباك لا نهاية له بين ميزات لغة البرمجة الياقوت وتنفيذ روبي معين.

    ويسمى أحيانًا "التصوير بالرنين المغناطيسي" (ل "تطبيق Matz's Ruby") أو Cruby أو Matzruby.

    تصوير التصوير بالرنين المغناطيسي ينفذ خيوط الياقوت كخيط خضراء داخل مترجمها.لسوء الحظ ، لا يسمح بجدولة هذه الخيوط بالتوازي ، ويمكنها فقط تشغيل مؤشر ترابط واحد في وقت واحد.

    ومع ذلك ، يمكن أن يعمل أي عدد من مؤشرات الترابط C (مؤشرات ترابط POSIX وما إلى ذلك) بالتوازي مع مؤشر ترابط Ruby ، ​​لذلك لا يزال بإمكان LATE CANTERSENTS Extensions Office Clants One Onshernal Onderts تشغيل مؤشرات ترابط خاصة بهم بشكل متوازٍ.

  2. التنفيذ الثاني هو YARV (قصير لـ "Ruby VM آخر"). YARV ينفذ مؤشرات ترابط Ruby كما POSIX أو Windows NT Threads, ، ومع ذلك ، فإنه يستخدم قفل مترجم عالمي (GIL) للتأكد من أنه يمكن بالفعل جدولة مؤشر ترابط روبي واحد فقط في أي وقت.

    مثل التصوير بالرنين المغناطيسي، وخيوط C يستطيع في الواقع يعمل بالتوازي مع Ruby Threads.

    في المستقبل، من الممكن أن يكون GIL قد يتم تقسيمها إلى أقفال مزيد من الحبيبات ، وبالتالي السماح بمزيد من التعليمات البرمجية للتشغيل بالتوازي فعليًا ، لكن هذا بعيد جدًا ، فهو ليس حتى المخطط لها حتى الآن.

  3. جي روبي تنفذ خيوط روبي كخيوط أصلية, ، حيث من الواضح أن "المواضيع الأصلية" في حالة JVM تعني "خيوط JVM".لا يفرض JRuby أي قفل إضافي عليهم.لذلك ، ما إذا كان يمكن أن تعمل هذه الخيوط فعليًا بالتوازي على JVM:بعض JVMs تنفذ مؤشرات ترابط JVM كمواضيع OS وبعضها كخيط خضراء.(تستخدم أجهزة JVM السائدة من Sun/Oracle سلاسل عمليات نظام التشغيل حصريًا منذ JDK 1.3)

  4. Xروبي أيضًا ينفذ Ruby Threads كخيوط JVM. تحديث:لقد مات اكسروبي.

  5. أيرون روبي تنفذ خيوط روبي كخيوط أصلية, ، حيث من الواضح أن "المواضيع الأصلية" في حالة CLR تعني "مؤشرات الترابط CLR".لا يفرض Ironruby أي قفل إضافي عليها ، لذلك ، يجب أن يعملوا بالتوازي ، طالما أن CLR يدعم ذلك.

  6. روبي.نت أيضًا ينفذ خيوط Ruby كخيط CLR. تحديث: روبي.نت ميت.

  7. روبينيوس ينفذ خيوط الياقوت كخيط خضراء داخل جهازها الظاهري.أكثر دقة:يقوم Rubinius VM بتصدير تزامن خفيف للغاية ومرن للغاية/موازٍ/بنية للتدفق غير المحلي ، يسمى "مهمة"، وجميع بنيات التزامن الأخرى (مؤشرات الترابط في هذه المناقشة ، ولكن أيضًا استمرار, ممثلين وأشياء أخرى) يتم تنفيذها في روبي نقي ، باستخدام المهام.

    لا يمكن لـ Rubinius (حاليًا) جدولة المواضيع بالتوازي ، مع ذلك ، مضيفًا أنه ليس مشكلة كبيرة:يمكن روبينيوس بالفعل قم بتشغيل العديد من مثيلات VM في عدة خيوط Posix بالتوازي, ، ضمن عملية روبينيوس واحدة.نظرًا لأن المواضيع يتم تنفيذها فعليًا في Ruby ، ​​يمكن ، مثل أي كائن Ruby آخر ، التسلسل وإرسالها إلى VM مختلف في مؤشر ترابط POSIX مختلف.(هذا هو نفس النموذج BEAM إرلانج يستخدم VM للتزامن SMP.هو بالفعل تم تنفيذها لممثلي Rubinius.)

    تحديث:المعلومات حول Rubinius في هذه الإجابة تتعلق بـ Shotgun VM، الذي لم يعد موجودًا.لا يستخدم جهاز C++ VM "الجديد" مؤشرات الترابط الخضراء المجدولة عبر أجهزة افتراضية متعددة (أي.Erlang/BEAM)، فهو يستخدم جهازًا افتراضيًا فرديًا أكثر تقليدية مع نماذج سلاسل عمليات نظام تشغيل أصلية متعددة، تمامًا مثل النموذج الذي يستخدمه، على سبيل المثال، CLR وMono وكل JVM تقريبًا.

  8. ماكروبي بدأ كمنفذ YARV أعلى وقت تشغيل Objective-C و CoreFoundation و Cocoa.لقد تباعدت الآن بشكل كبير عن Yarv ، لكن Afaik لا يزال حاليًا يشترك في نفس نموذج الترابط مع YARV. تحديث: يعتمد MacRuby على أداة تجميع البيانات المهملة من التفاح والتي تم الإعلان عن إهمالها وستتم إزالتها في الإصدارات اللاحقة من MacOSX، MacRuby هو أوندد.

  9. أساسي هو تنفيذ روبي ل ببغاء الجهاز الظاهري.ومع ذلك ، فإنه لا ينفذ مؤشرات الترابط بعد ذلك عندما يحدث ذلك ، فمن المحتمل أن ينفذها كـ ببغاء المواضيع. تحديث:يبدو الكاردينال غير نشط/ميت جدًا.

  10. ماجليف هو تنفيذ روبي ل الأحجار الكريمة/s smalltalk vm.ليس لدي أي معلومات ما يستخدمه نموذج الأحجار الكريمة/S Thinding ، أو ما يستخدمه Maglev لترابط أو حتى إذا تم تنفيذ مؤشرات الترابط حتى الآن (ربما لا).

  11. HotRuby يكون لا تنفيذ روبي كامل من تلقاء نفسه.إنه تنفيذ ل yarv bytecode VM في JavaScript.Hotruby لا يدعم المواضيع (حتى الآن؟) وعندما تفعل ذلك ، لن يتمكنوا من الركض بالتوازي ، لأن JavaScript ليس له أي دعم للتوازي الحقيقي.هناك إصدار ActionScript من HotRuby ، ​​ومع ذلك ، وقد تدعم ActionScript التوازي بالفعل. تحديث:لقد مات هوتروبي.

لسوء الحظ ، اثنان فقط من تطبيقات Ruby ال 11 هذه جاهز للإنتاج بالفعل:التصوير بالرنين المغناطيسي وJRuby.

لذلك ، إذا كنت تريد خيوط متوازية حقيقية ، فإن JRuby هو حاليا الخيار الوحيد - ليس هذا سيئا:JRuby هو في الواقع أسرع من التصوير بالرنين المغناطيسي ، ويمكن القول أكثر استقرارا.

خلاف ذلك ، فإن حل روبي "الكلاسيكي" هو استخدام العمليات بدلا من خيوط التوازي.مكتبة روبي الأساسية يحتوي على Process وحدة مع ال Process.fork طريقة مما يجعل من السهل التخلص من روبي آخر عملية.تحتوي مكتبة Ruby Standard Library أيضًا علىالياقوت الموزع (dRuby / dRb) المكتبة ، والتي تسمح روبي التعليمات البرمجية ليتم توزيعها بشكل تافه عبر عمليات متعددة ، وليس فقط على نفس الجهاز ولكن أيضا عبر الشبكة.

نصائح أخرى

يحتوي Ruby 1.8 على سلاسل خضراء فقط، ولا توجد طريقة لإنشاء سلاسل رسائل حقيقية على "مستوى نظام التشغيل".لكن روبي 1.9 سيحتوي على ميزة جديدة تسمى الألياف، والتي ستسمح لك بإنشاء سلاسل رسائل فعلية على مستوى نظام التشغيل.لسوء الحظ، لا يزال Ruby 1.9 في مرحلة تجريبية، ومن المقرر أن يكون مستقرًا في غضون شهرين.

بديل آخر هو استخدام JRuby.تطبق JRuby سلاسل الرسائل كإعلانات على مستوى نظام التشغيل، ولا توجد "سلاسل خضراء" فيها.أحدث إصدار من JRuby هو 1.1.4 ويعادل Ruby 1.8

يعتمد التنفيذ على:

  • لا يوجد تصوير بالرنين المغناطيسي، YARV أقرب.
  • JRuby وMacRuby لديهما.




روبي لديها الإغلاق مثل Blocks, lambdas و Procs.للاستفادة الكاملة من عمليات الإغلاق والنوى المتعددة في JRuby، منفذي جافا تأتي في متناول اليدين؛لMacRuby أحب طوابير GCD.

لاحظ أنه قادر على الإنشاء المواضيع الحقيقية "على مستوى نظام التشغيل". لا يعني ذلك أنه يمكنك استخدام نوى وحدة المعالجة المركزية المتعددة للمعالجة المتوازية.انظر إلى الأمثلة أدناه.

هذا هو الناتج برنامج روبي بسيط يستخدم 3 خيوط باستخدام روبي 2.1.0:

(jalcazar@mac ~)$ ps -M 69877
USER     PID   TT   %CPU STAT PRI     STIME     UTIME COMMAND
jalcazar 69877 s002    0.0 S    31T   0:00.01   0:00.04 /Users/jalcazar/.rvm/rubies/ruby-2.1.0/bin/ruby threads.rb
   69877         0.0 S    31T   0:00.01   0:00.00 
   69877        33.4 S    31T   0:00.01   0:08.73 
   69877        43.1 S    31T   0:00.01   0:08.73 
   69877        22.8 R    31T   0:00.01   0:08.65 

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



نفس البرنامج، الآن مع JRuby.يمكنك رؤية ثلاثة مواضيع مع الحالة R, مما يعني أنهما يعملان بالتوازي.

(jalcazar@mac ~)$ ps -M 72286
USER     PID   TT   %CPU STAT PRI     STIME     UTIME COMMAND
jalcazar 72286 s002    0.0 S    31T   0:00.01   0:00.01 /Library/Java/JavaVirtualMachines/jdk1.7.0_25.jdk/Contents/Home/bin/java -Djdk.home= -Djruby.home=/Users/jalcazar/.rvm/rubies/jruby-1.7.10 -Djruby.script=jruby -Djruby.shell=/bin/sh -Djffi.boot.library.path=/Users/jalcazar/.rvm/rubies/jruby-1.7.10/lib/jni:/Users/jalcazar/.rvm/rubies/jruby-1.7.10/lib/jni/Darwin -Xss2048k -Dsun.java.command=org.jruby.Main -cp  -Xbootclasspath/a:/Users/jalcazar/.rvm/rubies/jruby-1.7.10/lib/jruby.jar -Xmx1924M -XX:PermSize=992m -Dfile.encoding=UTF-8 org/jruby/Main threads.rb
   72286         0.0 S    31T   0:00.00   0:00.00 
   72286         0.0 S    33T   0:00.00   0:00.00 
   72286         0.0 S    31T   0:00.09   0:02.34 
   72286         7.9 S    31T   0:00.15   0:04.63 
   72286         0.0 S    31T   0:00.00   0:00.00 
   72286         0.0 S    31T   0:00.00   0:00.00 
   72286         0.0 S    31T   0:00.00   0:00.00 
   72286         0.0 S    31T   0:00.04   0:01.68 
   72286         0.0 S    31T   0:00.03   0:01.54 
   72286         0.0 S    31T   0:00.00   0:00.00 
   72286         0.0 S    31T   0:00.01   0:00.01 
   72286         0.0 S    31T   0:00.00   0:00.01 
   72286         0.0 S    31T   0:00.00   0:00.03 
   72286        74.2 R    31T   0:09.21   0:37.73 
   72286        72.4 R    31T   0:09.24   0:37.71 
   72286        74.7 R    31T   0:09.24   0:37.80 


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

(jalcazar@mac ~)$ ps -M 38293
USER     PID   TT   %CPU STAT PRI     STIME     UTIME COMMAND
jalcazar 38293 s002    0.0 R     0T   0:00.02   0:00.10 /Users/jalcazar/.rvm/rubies/macruby-0.12/usr/bin/macruby threads.rb
   38293         0.0 S    33T   0:00.00   0:00.00 
   38293       100.0 R    31T   0:00.04   0:21.92 
   38293       100.0 R    31T   0:00.04   0:21.95 
   38293       100.0 R    31T   0:00.04   0:21.99 


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

(jalcazar@mac ~)$ ps -M 70032
USER     PID   TT   %CPU STAT PRI     STIME     UTIME COMMAND
jalcazar 70032 s002  100.0 R    31T   0:00.08   0:26.62 /Users/jalcazar/.rvm/rubies/ruby-1.8.7-p374/bin/ruby threads.rb



إذا كنت مهتمًا بـ Ruby multi-threading، فقد تجد تقريري تصحيح أخطاء البرامج المتوازية باستخدام معالجات الشوكة مثير للاهتمام.
للحصول على نظرة عامة أكثر عمومية عن الأجزاء الداخلية لروبي روبي تحت المجهر هي قراءة جيدة.
أيضًا، خيوط روبي وقفل المترجم العالمي في لغة C في Omniref يشرح في الكود المصدري سبب عدم تشغيل سلاسل روبي بالتوازي.

ماذا عن استخدام drb؟إنها ليست سلاسل عمليات متعددة حقيقية ولكنها اتصال بين عدة عمليات، ولكن يمكنك استخدامها الآن في الإصدار 1.8 وهي منخفضة الاحتكاك إلى حد ما.

سأدع "مراقب النظام" يجيب على هذا السؤال.أقوم بتنفيذ نفس الكود (أدناه، الذي يحسب الأعداد الأولية) مع 8 خيوط روبي تعمل على جهاز i7 (4 نواة مفرطة الترابط) في كلتا الحالتين...التشغيل الأول يكون مع:

JRUBY 1.5.6 (روبي 1.8.7 مستوى التصحيح 249) (2014-02-03 6586) (OpenJDK 64 بت خادم VM 1.7.0_75) [amd64 - جافا]

والثاني مع:

روبي 2.1.2p95 (08/05/2014) [x86_64-لينكس-جنو]

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

enter image description here

def eratosthenes(n)
  nums = [nil, nil, *2..n]
  (2..Math.sqrt(n)).each do |i|
    (i**2..n).step(i){|m| nums[m] = nil}  if nums[i]
  end
  nums.compact
end

MAX_PRIME=10000000
THREADS=8
threads = []

1.upto(THREADS) do |num|
  puts "Starting thread #{num}"
  threads[num]=Thread.new { eratosthenes MAX_PRIME }
end

1.upto(THREADS) do |num|
    threads[num].join
end

إذا كنت تستخدم التصوير بالرنين المغناطيسي، فيمكنك كتابة الكود المترابط بلغة C إما كامتداد أو باستخدام جوهرة روبي المضمنة.

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

أيضًا، إذا كنت مهتمًا بمستقبل الترابط ضمن روبي، فقد تجد هذا شرط مفيد.

فيما يلي بعض المعلومات عن Rinda وهو تنفيذ Ruby لـ Linda (نموذج المعالجة المتوازية والحوسبة الموزعة) http://charmalloc.blogspot.com/2009/12/linda-tuples-rinda-drb-parallel.html

لأنه لا يمكن تعديل هذه الإجابة، لذا قم بإضافة رد جديد هنا.

تحديث(2017-05-08)

هذه المقالة قديمة جدا والمعلومات لا تتبع الحالية (2017) فقي ، فيما يلي بعض الملحقات:

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

  2. truffleruby هو تطبيق عالي الأداء للغة برمجة روبي.تم بناء TruffleRuby على GraalVM بواسطة Oracle Labs، وهو عبارة عن شوكة من JRuby، حيث يتم دمجه مع التعليمات البرمجية من مشروع Rubinius، ويحتوي أيضًا على تعليمات برمجية من التنفيذ القياسي لـ Ruby، MRI، الذي لا يزال قيد التطوير، وليس جاهزًا للإنتاج.يبدو أن هذا الإصدار من روبي قد ولد من أجل الأداء، ولا أعرف ما إذا كان يدعم الخيوط المتوازية، ولكن أعتقد أنه ينبغي ذلك.

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