DISQUS

time to bleed by Joe Damato: Ruby threading bugfix: small fix goes a long way.

  • Hongli Lai · 1 year ago
    Nice! Have you considered submitting this patch to upstream?


    "What this means for the Ruby developer is that any thread which does I/O will cause the entire ruby process (the ruby interpretter and all ruby green threads) to block."

    Sorry, gotta disagree with you here. The MRI core I/O implementation is essentially non-blocking. If it detects that an I/O operation will block, it will simply set the thread's state to 'blocking on I/O' and schedule another green thread instead.

    Consider this:
    require 'thread'
    require 'socket'

    thread = Thread.new do
    while true
    puts rand
    sleep 1
    end
    end

    TCPSocket.new('www.google.com', 80).read

    Look! The thread keeps running even though we're blocked on a read operation.

    What is true however, is that native extensions that:
    1. use blocking I/O
    and
    2. aren't explicitly programmed to support green threads (i.e. to cause a context switch when it detects a potentially blocking condition)
    will block all green threads. The MySQL library is one such example.
  • Jesse · 1 year ago
    My phone interview question at YouTube was "How would you build a thread scheduler?"

    A stupid question for a phone interview (and the interviewer was entirely too please with himself), but I'm interested in seeing the answer from someone who knows what they're talking about, i.e., not me.
  • joe · 1 year ago
    @Hongli Lai: Thanks for the comments - I will try to make my posts more clear in the future.

    You are correct that ruby attempts to do non-blocking I/O whenever possible, but it cannot control what the ruby extensions do. So if your ruby extension does blocking I/O, your Ruby process blocks.

    I also want to point out that when the actual I/O is occurring (in your example, when there is data for read) that I/O operation WILL block all of Ruby and all green threads.

    I plan on writing a blog post or two soon that will talk about different I/O models (blocking vs nonblocking vs async) and I'll touch more on these details there.

    Again, thanks for reading and I'll make some corrections to my post to make it more clear.
  • rogerdpack · 1 year ago
    @hongli the mysqlplus library doesn't block if you use async_query :) [oh wait, you probably already knew that].

    MRI 1.8.x does use a "non blocking" internal IO--kind of slow [1] but it works.

    I'd say definitely submit a patch to core for this one -- others may benefit :) -- wonder if 1.9 is affected [though know nothing about it].

    Maybe somebody should actually buy something from software verify :)

    Thanks for doing these.

    -=R

    [1] http://www.ruby-forum.com/topic/164329#new
  • joe · 1 year ago
    @roger - This patch has been submit to ruby-core. Also, ruby uses asynchronous blocking I/O.

    Stay tuned for a new timetobleed article about different I/O models.

    Thanks for reading!
  • Roman · 1 year ago
    Thanks for the patch, it finally fixed that SIGVTALRM weirdness that I was experiencing. Too bad that I ran in circles trying to understand what I'm doing wrong, when in fact it was a VM bug. But it seems that your fix is not even in the latest 1.8.7 snapshot. Perhaps you need to bug ruby-core again in order to include it.
  • Ian Lesperance · 10 months ago
    We're using 1.8.5 p115 and are running into this SIGVTALRM weirdness with Phusion Passenger. I tried adapting the patch for 1.8.5 and came up with the following:

    http://www.elliterate.com/files/ruby_1.8.5_sigv...

    Any reason why this couldn't work? It doesn't seem to be causing any problems (yet) on our staging server.
  • Georgia Sewall · 5 months ago
    do you have a thread called "shrinking thread"...happened to see a quilting show on TV...guest was showing a pillow she had covered and one of the swatches was made w/shrinking thread...made the surface look like it was wrinkled....very atractive....