Stephen W. wrote:
Hi guys, sorry if this is a stupid question, but I’ve been reading
around online and in ‘Programming Ruby,’ and I can’t find anything.
Is there a way to perform a non-blocking gets or getc? As in a method
that reads a character from stdin if there is one in the buffer or
returns nil otherwise? I’m writing a multi-threaded application that
communicates over the internet using sockets, but I want the person who
runs the script on the host machine to be able to enter commands via
stdin. The ‘gets’ command hangs all my threads until it returns.
The following is an example that uses one thread to execute some code in
the background while another thread waits for user input. After being
prompted for input, if you wait 5 seconds before entering any input, you
will see that the background thread’s output is written to the file
while the main thread waits for your input.
If instead, you enter your input right away, you will see that what you
entered will be interleaved with the thread’s output.
require “monitor”
f = File.new(“aaa.txt”, “w”)
lock = Monitor.new
t = Thread.new do
lock.synchronize do
f.puts(“thread output1”)
end
sleep(3)
lock.synchronize do
f.puts(“thread output2”)
end
end
print "Enter command: "
STDOUT.flush
input = gets
lock.synchronize do
f.puts(input)
end
t.join
f.close
File.open(“aaa.txt”) do |file|
print file.read
end
–output:–
(waiting 5 seconds):
Enter command: hello
thread ouput1
thread output2
hello
(entering input immediately when prompted):
Enter command: hello
thread output1
hello
thread output2
One thing I found puzzling is having to call STOUT.flush. When I don’t
include that statement, then the print statement is skipped. Yet, if I
use puts instead of print, then the flush call isn’t necessary. Anyone
know why?