Ruby Mulithreading

H

Hello There

Hi

I've been recently encountered a major problem with a program i am
coding.
Main in my program outputs a menu with some cases you can choose,
1,2,3.. so i have a gets at the end of the menu. However, my program
also checks for timestamps with a seperate thread (thread 2). And it
appeared that the thread bugged when I used gets, since i have 3 if
conditions in my thread 2, and if i for example replace gets with
sleep(200), the if conditions runs as it should. But when I have the
gets, it never runs. Later I found out that there is appearently a bug
in Ruby with standard I/O and threads in Windows?

So, how can i workaround this bug? Is there any alternative method for
input or so?

Thanks
 
B

Bill Kelly

From: "Hello There said:
I've been recently encountered a major problem with a program i am
coding.
Main in my program outputs a menu with some cases you can choose,
1,2,3.. so i have a gets at the end of the menu. However, my program
also checks for timestamps with a seperate thread (thread 2). And it
appeared that the thread bugged when I used gets, since i have 3 if
conditions in my thread 2, and if i for example replace gets with
sleep(200), the if conditions runs as it should. But when I have the
gets, it never runs. Later I found out that there is appearently a bug
in Ruby with standard I/O and threads in Windows?

It's more like a bug (or "misfeature") of Windows, in that select() is
broken for file handles and pipes. Prior to ruby 1.9, ruby uses
select() internally to wait for I/O while performing its own thread
scheduling.
So, how can i workaround this bug? Is there any alternative method for
input or so?

Ruby 1.9 will work, since 1.9 now uses OS native threads. So gets()
will block its thread, without blocking the whole process.

If you need to use 1.8, it is possible to write a nonblocking gets on
windows using kbhit/getch:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

require 'Win32API'

class Win32GetsNonblock
@@kbhit_proc = Win32API.new("msvcrt", "_kbhit", [], 'I')
@@getch_proc = Win32API.new("msvcrt", "_getch", [], 'I')

class << self
def gets
str = ""
begin
ch = getch
ch = ?\n if ch == ?\r
str << ch.chr
end until ch == ?\n
str
end

def kbhit
@@kbhit_proc.call != 0
end

def getch
sleep 0.1 until kbhit
@@getch_proc.call
end
end
end


# example.......

th = Thread.new { loop {puts Time.now; sleep 1} }

x = Win32GetsNonblock.gets
p x

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Note, I have only tried the above on
ruby 1.8.4 (2005-12-24) [i386-mswin32]


Hope this helps,

Bill
 
H

Hello There

Hi
Thank you very much for answer.

What if i want the code to be able to run on linux aswell?

Also, I tried installing Ruby 1.9.1, but some of the libs i use e.g
Nokogiri is appearently not supported in 1.9.

best regards
 
B

Bill Kelly

From: "Hello There said:
What if i want the code to be able to run on linux aswell?

gets doesn't block other threads on Linux, because select() isn't
broken on Linux.

So... one possibility would be to define a nonblocking gets method,
which on Linux is just aliased to the original gets, since it works.
But on windows, uses the nonblocking implementation.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

if PLATFORM =~ /mswin/
def getsnb
# do nonblocking gets using kbhit/getch as in previous email
end
else
alias :getsnb :gets
end


# Example...

x = getsnb

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


Perhaps a cleaner approach would be to make a module which
provides a replacement for gets on windows only. On non-windows
systems, the module would be empty.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

module NonblockGets
if PLATFORM =~ /mswin/
def gets
# do nonblocking gets using kbhit/getch as in previous email
end
end
end


# Example....

class MyClass
include NonblockGets

def my_method
x = gets # on windows, this will be the gets defined in NonblockGets module
end
end

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


Hope this helps,

Bill
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,172
Messages
2,570,934
Members
47,478
Latest member
ReginaldVi

Latest Threads

Top