Bill Kelly
5/24/2009 11:17:00 PM
From: "Hello There" <abbb812@gmail.com>
>
> 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