Trouble using puts and getc in different threads

Hi,

I was trying to do a little exercise: Display series of numbers
(1,2,3,4, 5…etc) in an infinite loop. The program should quit if
someone hits a specific key (ENTER in my case as the escape key
requires ugly solutions for non-buffered input). Sounds simple, right?
Not. I thought this should work:

$done = FALSE

Thread.new do
STDIN.getc
$done = TRUE
end

i = 0
while !$done
i = i + 1
puts i
end
puts “We’re done here…”

It doesn’t work. What I see is the loop running until i equals 60 then
the loop stops! When I press ENTER, the program stops (as expected).

If I replace STDIN.getc by a sleep(3) then the loop runs for 3 seconds
as expected and the program terminates.

My conclusion: using puts and getc in different threads causes
trouble. Why is this? How can this be fixed? Should I go about the
‘loop until key pressed’-problem’ in an entirely different way?

Thanx!
Mark

On 10/23/06, Mark [email protected] wrote:

Hi,

I was trying to do a little exercise: Display series of numbers
(1,2,3,4, 5…etc) in an infinite loop. The program should quit if
someone hits a specific key (ENTER in my case as the escape key
requires ugly solutions for non-buffered input). Sounds simple, right?
Not. I thought this should work:

Try it on a Unix-like system. It will work. We’ve had several
discussions
here about an bad interaction between Ruby threads and system I/O on
Windows, but I’m not sure anyone has gotten to the bottom of it.

On 10/23/06, Francis C. [email protected] wrote:

Try it on a Unix-like system. It will work. We’ve had several discussions
here about an bad interaction between Ruby threads and system I/O on
Windows, but I’m not sure anyone has gotten to the bottom of it.

Hmm, that was not the answer I was hoping for… And I don’t have the
luxury of using a linux computer. :frowning:

Does this mean that is not possible to write a ruby program that
continuously outputs data on stdout until a key is pressed by the
user? It sounds so simple.

I found a posting from Nobu Nokada in 2002 saying “Another problem due
to select(), thread cannot switch while console input.” which
explaines my code doesn’t work. Must I draw the conclusion that this
problem still isn’t fixed?

Mark

On 10/23/06, Mark [email protected] wrote:

user? It sounds so simple.

I found a posting from Nobu Nokada in 2002 saying “Another problem due
to select(), thread cannot switch while console input.” which
explaines my code doesn’t work. Must I draw the conclusion that this
problem still isn’t fixed?

if you’re on windows, see [1] thread for a solution, especially [2]
(using kbhit()) and
[3] (using select)

[1] http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/204589
[2] http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/204863
[3] http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/205002

I am on a windows machine, and oddly enough I ran it the code. it went
to 59 then when I hit enter, it printed 60 We’re done here …

Is that what it was supposed to do?

On 10/23/06, Jan S. [email protected] wrote:

if you’re on windows, see [1] thread for a solution, especially [2]
(using kbhit()) and
[3] (using select)

[1] http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/204589
[2] http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/204863
[3] http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/205002

I’m still wondering what the problem with #getc is. Is it possible that
the
way Ruby implements it is not interruptible in Windows, so Ruby can’t
run
the thread scheduler around it?

Jeremy W. wrote:

I am on a windows machine, and oddly enough I ran it the code. it went
to 59 then when I hit enter, it printed 60 We’re done here …

Is that what it was supposed to do?

Uh no. I expect the loop to run until I press Enter and not stop before
that.

Francis & Jan thanks.

Maybe the problem has to do with the fact that input from STDIN is
echoed. This requires using STDOUT. Maybe STDIN’s thread locks STDOUT?
But I’m also guessing that other much more knowledgeable people than I
have had thoughts about this. I’m just having trouble finding those
posts.

As I’m not going to be writing lots of interactive console applications,
I’m not going to put more effort into this. It’s clear to me that this
is a bug in Ruby’s implementation for windows.

Mark