Ask a Question related to Ruby, Design and Development.
-
Thomas Sondergaard #1
Thread safety: Serializing access to ruby interpreter- again
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 Guest
-
Thread safety/synchronization?
Flex/AS doesn't appear to have any overt synchronization mechanism, is it handled under the covers (ie is every method synchronized?) or is it user... -
apartmant thread safety
I'm rather confused about this whole threading business of IIS, ASP and COM components. We have an apartment threaded component with a function... -
Trying to figure out thread safety
(Having been told of a solution to one problem (File::CREAT was indeed what was needed), I'll now go off on something entirely different.) I've... -
Ruby interpreter thread safety
I have a scenario where a ruby extension module starts real/os/heavy-weight threads that may call back to ruby. As far as I understand the ruby... -
Thread safety of vm_copy
I tried looking around for explicit documentation on this but to no avail, perhaps it is too basic. On Mac OS X the Mach function vm_copy has a... -
nobu.nokada@softhome.net #2
Re: Thread safety: Serializing access to ruby interpreter- again
Hi,
At Thu, 18 Sep 2003 09:32:21 +0900,
Thomas Sondergaard wrote:Using a pipe (or any IO) as the trigger which wakes Monitor up.> 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?
Agree, but wait until 1.9 or perhaps 2.0.> Is there a heavyweight-thread-safe way to wake up a ruby thread? Shouldn't
> there be?
--
Nobu Nakada
nobu.nokada@softhome.net Guest
-
Thomas Sondergaard #3
Re: Thread safety: Serializing access to ruby interpreter- again
Hi Nobu,
That doesn't work. Blocking on a pipe (or any IO) in Windows blocks the> Using a pipe (or any IO) as the trigger which wakes Monitor up.
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 Guest
-
nobu.nokada@softhome.net #4
Re: Thread safety: Serializing access to ruby interpreter- again
Hi,
At Fri, 19 Sep 2003 17:37:09 +0900,
Thomas Sondergaard wrote:Socket might work.>> > 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.
Because winsock's select() supports only socket handles.> Out of curiousity, why does this happen on Windows? Is it not fixable?
--
Nobu Nakada
nobu.nokada@softhome.net Guest
-
Thomas Sondergaard #5
Re: Thread safety: Serializing access to ruby interpreter- again
If you say so, I'll give it a try.> Socket might work.
Is all ruby IO implemented in terms of select to avoid blocking the process?>> > Out of curiousity, why does this happen on Windows? Is it not fixable?
> Because winsock's select() supports only socket handles.
Why doesn't select block the process, btw?
Thomas
Thomas Sondergaard Guest
-
Simon Kitching #6
Re: Thread safety: Serializing access to ruby interpreter- again
On Wed, 2003-09-24 at 21:38, Thomas Sondergaard wrote:
Well, I'm a newbie to Ruby, but unfortunately old enough to remember>> > 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
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 Guest



Reply With Quote

