From: Bill Kelly Date: 2009-05-25T08:17:25+09:00 Subject: Re: Ruby Mulithreading From: "Hello There" > > 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