Thread safety: Serializing access to ruby interpreter- again

Discussion in 'Ruby' started by Thomas Sondergaard, Sep 18, 2003.

  1. I recently asked about this and got answers, but here I go again:

    How can I efficiently serialize access to the ruby interpreter. I have to
    make sure all access to the ruby interpreter happens on a particular thread
    (not a ruby thread, mind you), so when a different thread attempts to access
    the ruby interpreter I need it to have it post the job to a queue and then
    wait for a ruby worker thread on the ruby-thread :)-)) to execute whatever
    it needs done. Btw, in this mail I use the term ruby-thread, with a dash in
    the middle, as a reference to the heavy-weight thread in which the ruby
    interpreter executes.

    The thing is that if I have a ruby thread on the ruby-thread block on a
    heavyweight thread lock the entire ruby-thread is blocked. This is
    demonstrated by this bit below (which requires my dotnet module to work). It
    simply starts a thread that writes to the console continuously and then the
    main thread waits for a signal on anObject. However that wait() call blocks
    the entire ruby-thread not just the "green" ruby main thread, so I never get
    to see a steady stream of hello worlds, and that is what ruins my day.

    require 'dotnet'

    t = Thread.new { while true; sleep 0.1; puts "hello world"; end }

    anObject = System::EventArgs.new

    System::Threading::Monitor.enter(anObject)
    System::Threading::Monitor.wait(anObject) # This blocks the entire
    ruby-thread
    System::Threading::Monitor.exit(anObject)

    t.join


    So if I am not allowed to touch the ruby interpreter from other threads than
    the ruby-thread how can I wake up a sleeping worker thread when there is
    something for it to do?

    Is there a heavyweight-thread-safe way to wake up a ruby thread? Shouldn't
    there be?

    - Thomas
    Thomas Sondergaard, Sep 18, 2003
    #1
    1. Advertising

  2. Thomas Sondergaard

    Guest

    Hi,

    At Thu, 18 Sep 2003 09:32:21 +0900,
    Thomas Sondergaard wrote:
    > So if I am not allowed to touch the ruby interpreter from other threads than
    > the ruby-thread how can I wake up a sleeping worker thread when there is
    > something for it to do?


    Using a pipe (or any IO) as the trigger which wakes Monitor up.

    > Is there a heavyweight-thread-safe way to wake up a ruby thread? Shouldn't
    > there be?


    Agree, but wait until 1.9 or perhaps 2.0.

    --
    Nobu Nakada
    , Sep 18, 2003
    #2
    1. Advertising

  3. Hi Nobu,

    > Using a pipe (or any IO) as the trigger which wakes Monitor up.


    That doesn't work. Blocking on a pipe (or any IO) in Windows blocks the
    entire ruby process. This sample will just block and get no where in Windows
    after writing "hello from main" once, while in Linux it happily prints
    "hello from main" once a second.

    readPipe, writePipe = IO.pipe

    t = Thread.new { while true; sleep 1; puts "got #{readPipe.readline}"; end }

    while true
    sleep 1
    puts "hello from main"
    end

    t.join


    Out of curiousity, why does this happen on Windows? Is it not fixable?

    Tom
    Thomas Sondergaard, Sep 19, 2003
    #3
  4. Thomas Sondergaard

    Guest

    Hi,

    At Fri, 19 Sep 2003 17:37:09 +0900,
    Thomas Sondergaard wrote:
    > > Using a pipe (or any IO) as the trigger which wakes Monitor up.

    >
    > That doesn't work. Blocking on a pipe (or any IO) in Windows blocks the
    > entire ruby process. This sample will just block and get no where in Windows
    > after writing "hello from main" once, while in Linux it happily prints
    > "hello from main" once a second.


    Socket might work.

    > Out of curiousity, why does this happen on Windows? Is it not fixable?


    Because winsock's select() supports only socket handles.

    --
    Nobu Nakada
    , Sep 24, 2003
    #4

  5. > Socket might work.


    If you say so, I'll give it a try.

    > > Out of curiousity, why does this happen on Windows? Is it not fixable?

    >
    > Because winsock's select() supports only socket handles.


    Is all ruby IO implemented in terms of select to avoid blocking the process?
    Why doesn't select block the process, btw?

    Thomas
    Thomas Sondergaard, Sep 24, 2003
    #5
  6. On Wed, 2003-09-24 at 21:38, Thomas Sondergaard wrote:
    > > Socket might work.

    >
    > If you say so, I'll give it a try.
    >
    > > > Out of curiousity, why does this happen on Windows? Is it not fixable?

    > >
    > > Because winsock's select() supports only socket handles.

    >
    > Is all ruby IO implemented in terms of select to avoid blocking the process?
    > Why doesn't select block the process, btw?
    >
    > Thomas


    Well, I'm a newbie to Ruby, but unfortunately old enough to remember
    writing C code before real threads existed.

    I'm guessing Ruby threads work in the old "cooperative" manner, as
    follows:

    What you would do is replace blocking calls to read operations with
    calls to functions implemented like this:

    read_from_socket:

    for(;;) {
    check for data available
    if data is available
    read data and return it
    else
    schedule some other thread to run // aka "yield"
    }

    The check for data is done with a NON-BLOCKING select call, ie one that
    returns immediately even if no data is currently available. In that
    case, the current "thread" stops running and some other "thread" gets
    the CPU. Eventually the current "thread" is rescheduled, goes back to
    the top of the loop, and checks for data again.

    It was always a pain to code this way, because you had to call these
    "yielding" versions of standard library calls rather than the real ones,
    for every library function that might block.

    However given that languages like Ruby always have "glue" code for
    calling native operations like read & write, it works quite tidily for
    them.

    The disadvantage, of course, is that because all threading is
    implemented within a single real OS thread, the app can't take advantage
    of systems which really have multiple CPUs. And thread "pre-emption" is
    a bit flaky.

    I am guessing that Windows doesn't provide a way to check a socket for
    the presence of data without blocking, meaning that this just can't be
    implemented.

    Cheers,

    Simon
    Simon Kitching, Sep 24, 2003
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    3
    Views:
    758
    Ziga Seilnacht
    Jan 3, 2007
  2. Philipp
    Replies:
    7
    Views:
    464
    Volker Borchert
    May 6, 2008
  3. Thomas Sondergaard

    Ruby interpreter thread safety

    Thomas Sondergaard, Sep 4, 2003, in forum: Ruby
    Replies:
    4
    Views:
    118
    Thomas Sondergaard
    Sep 4, 2003
  4. Replies:
    4
    Views:
    97
    Robert Klemme
    Jan 23, 2006
  5. -= Ko =- Black Ninja
    Replies:
    1
    Views:
    313
    -= Ko =- Black Ninja
    Apr 5, 2011
Loading...

Share This Page