سؤال

أنا أكتب نصًا سيؤدي إلى ping نطاق IP الخاص بي. هذا ما لدي حتى الآن:

lines = `ipconfig`.split("\n")
thr = []
ip_line = lines.detect { |l| l=~/Ip Address/i }
matcher = /\d+\.\d+\.\d+\.\d+/.match(ip_line)
if matcher.length > 0
    address = matcher[0]
    address.sub!(/\.\d+$/,"")
    (1 .. 254).each do |i|
        xaddr = address + "." + i.to_s
        puts "pinging #{xaddr}"
        thr << Thread.new {
            `ping #{xaddr}` 
        }
    end

    thr.each do |t|
        t.join
        output = t.value
        puts output
    end
end

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

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

المحلول

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

`ping #{xaddr}`  

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

نصائح أخرى

يمكنك استخدام io.popen مثله

thr << Thread.new xaddr do |adr|
  IO.popen "ping #{adr}" do |io|
    io.each {|l| puts l}
  end
end

بهذه الطريقة تحصل على مزيد من التزامن حتى مع الخيوط الخضراء. والسبب هو أن المترجم المترجم لا يتعين عليه الانتظار حتى يتم إرسال الإخراج الكامل من ping.

ما هو تطبيق Ruby الذي تعمل عليه؟ في Ruby القياسية ، تكون المواضيع "خيوط خضراء" ، أي ليس مؤشرات ترابط نظام التشغيل الحقيقية ولكن توفرها وقت تشغيل Ruby.

في JRUBY ، تعد المواضيع مؤشرات ترابط OS حقيقية لأن هذه هي الطريقة التي ينفذ بها JVM.

لذلك ، قد ترى فرقًا في أداء الخيوط بين تطبيقات Ruby المختلفة. لاحظ أن Jruby يعتبر أسرع من أن Ruby 1.8.6 ، على الرغم من أن Ruby 1.9 أسرع من Jruby (على الأقل في بعض المعايير).

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