# Ruby Mulithreading

**URL:** <https://www.ruby-forum.com/t/ruby-mulithreading/168698>\
**Category:** Ruby\
**Created:** [May 24, 2009, 5:09pm UTC](https://www.ruby-forum.com/t/ruby-mulithreading/168698 "2009-05-24T17:09:11Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![hellothere1](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/a88e57/32.png) [@hellothere1](https://www.ruby-forum.com/u/hellothere1)\
**Post date:** [May 24, 2009, 5:09pm UTC](https://www.ruby-forum.com/t/ruby-mulithreading/168698/1 "2009-05-24T17:09:11Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![hellothere1](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/a88e57/32.png) [@hellothere1](https://www.ruby-forum.com/u/hellothere1)\
**Post date:** [May 25, 2009, 1:18am UTC](https://www.ruby-forum.com/t/ruby-mulithreading/168698/2 "2009-05-25T01:18:46Z")

</div>

From: “Hello There” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

> 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:

```auto

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

---

<div class="post-metadata">

**Author:** ![hellothere1](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/a88e57/32.png) [@hellothere1](https://www.ruby-forum.com/u/hellothere1)\
**Post date:** [May 25, 2009, 4:48pm UTC](https://www.ruby-forum.com/t/ruby-mulithreading/168698/3 "2009-05-25T16:48:44Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![hellothere1](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/a88e57/32.png) [@hellothere1](https://www.ruby-forum.com/u/hellothere1)\
**Post date:** [May 26, 2009, 12:46am UTC](https://www.ruby-forum.com/t/ruby-mulithreading/168698/4 "2009-05-26T00:46:12Z")

</div>

From: “Hello There” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

> 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.

```auto

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.

```auto

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
