Play with ruby threads

Play with ruby threads

6fa1cdda524d49996a8bc6917328de3d?s=128

Damien Mathieu

February 12, 2014
Tweet

Transcript

  1. Play with Ruby Threads

  2. Ruby Program Fetch URL A Fetch URL B End Program

  3. Ruby Program Fetch URL A Fetch URL B End Program

  4. require 'net/http' ! t1 = Thread.new { ! content =

    Net::HTTP.get(URI.parse("http://google.com")) puts "I just fetched google.com" } ! t2 = Thread.new { ! content = Net::HTTP.get(URI.parse("http://github.com")) puts "I just fetched github.com" } ! t1.join && t2.join puts "I've finished executing everything"
  5. › time ruby threads.rb! I just fetched google.com! I just

    fetched github.com! I've finished executing everything! ruby threads.rb 0.13s user 0.06s system 40% cpu 0.450 total
  6. require 'net/http' ! content = Net::HTTP.get(URI.parse("http://google.com")) puts "I just fetched

    google.com" ! content = Net::HTTP.get(URI.parse("http://github.com")) puts "I just fetched github.com" ! puts "I've finished executing everything"
  7. time ruby no_threads.rb! I just fetched google.com! I just fetched

    github.com! I've finished executing everything! ruby no_thread.rb 0.12s user 0.06s system 6% cpu 2.698 total
  8. 2.698 0.450 5.99

  9. Lifecycle of a thread

  10. Thread.new • Thread.new { … }! • Thread.fork { …

    }! • Thread.start(1, 2) { |x, y| … }
  11. Thread#join thread = Thread.new { sleep 3 } thread.join

  12. Thread#value thread = Thread.new do 400 + 5 end puts

    thread.value #=> 405
  13. Thread#status thread = Thread.new do Thread.current.status #=> 'run' 2 *

    3 end puts thread.status #=> 'run' thread.join puts thread.status #=> false
  14. Thread#stop thread = Thread.new do Thread.stop puts 'Hello there' end

    ! # wait for the thread to trigger its stop nil until thread.status == 'sleep' thread.wakeup thread.join
  15. Thread Safety

  16. Non-deterministic context switching • In order to provide fair access,

    the thread scheduler can pause a thread at any time
  17. Non-deterministic context switching class Post ! def comments @comments ||=

    [] end end
  18. Non-deterministic context switching class Post ! def comments if @comments.nil?

    temp = [] @comments = temp end end end
  19. Non-deterministic context switching class Post def initialize @comments_mutex = Mutex.new

    end ! def comments @comments_mutex.synchronize do @comments ||= [] end end end
  20. MRI’s GIL MRI has something called a global interpreter lock

    (GIL).! It's a lock around the execution of Ruby code.! This means that in a multi-threaded context, only one thread can execute Ruby code at any one time.
  21. MRI’s GIL So if you have 8 threads busily working

    on a 8-core machine, only one thread and one core will be busy at any given time.! The GIL exists to protect Ruby internals from race conditions that could corrupt data.! There are caveats and optimizations, but this is the gist.
  22. How many threads should I use? • Is your program

    IO or CPU bound?! • IO Bound will allow a lot of threads! • CPU Bound will depend of the number of cores! • The only way is to measure
  23. Resources

  24. http://ruby-doc.org/ core-2.1.0/Thread.html

  25. None
  26. http://bit.ly/ruby-threads