问题描述
解决方案::在.irbc文件中,放入:IRB.conf[:USE_READLINE] = false
SOLUTION: In .irbc file, put: IRB.conf[:USE_READLINE] = false
我正在运行一些ruby代码:
I am running some ruby code:
Thread.new do
loop do
a = @queue.pop
puts "1"
puts "2"
end
end
当我在irb中运行此命令并弹出队列时,它会显示"1",但不会立即显示"2".我必须按两次Enter键,然后才能吐出"2".为什么会这样?
When i run this in irb, and queue pops, it print "1", but doesn't print "2" right away. I have to press enter couple of times before it spits out "2". Why is that?
这是我的irb日志:
>> Thread.new do
?> loop do
?> a = @queue.pop
>> puts "1"
>> puts "2"
>> end
>> end
=> #<Thread:0x10ae6d1a0 sleep>
>> @queue << "something random"
1=> #<Queue:0x10aed6420>
>>
?>
?>
?>
2?>
这就是我得到的:
>> require "thread"
=> true
>>
?> @queue = Queue.new
=> #<Queue:0x101bc9a60>
>>
?> Thread.new do
?> loop do
?> a = @queue.pop
>> puts "1 was printed at #{Time.now.to_f}"
>> puts "2 was printed at #{Time.now.to_f}"
>> end
>> end
=> #<Thread:0x101bb8058 sleep>
>>
?> @queue << 42
1 was printed at 1328144684.33667=> #<Queue:0x101bc9a60>
>>
?>
?>
?>
2 was printed at 1328144686.4642?>
推荐答案
我进行了一些实验,发现了正在发生的事情.如您所知,两个Ruby线程不能同时运行.它们只是快速地来回切换.*通常,如果您调用gets
,则调用线程将等待输入,其他线程将继续(因为gets
释放 GIL ).但是,在irb中(至少在Mac OS X上是这样),其他线程在等待输入时不会继续执行.示例:
I experimented some and found out what is happening. As you might know, two Ruby threads cannot run at the same time; they just switch back and forth quickly.* Normally, if you call gets
, the calling thread will wait for input, and other threads will continue (because gets
releases the GIL ). However, in irb, (at least on Mac OS X) other threads do not continue to execute while it is waiting for input. Example:
>> i = 0
=> 0
>> Thread.new { loop { i += 1 } }
=> #<Thread:0x1094d6d68 run>
>> i
=> 234866
>> i
=> 401271
如果线程正在执行,则i
将以百万为单位. (在irb外部进行了测试.)此外,红宝石使用的是< 1%的CPU.
If the thread were executing, i
would be in the millions. (Tested outside irb.) Plus, ruby was using < 1% CPU.
在您的示例中,每次按Enter时,线程都会瞬间执行-足够的时间来写出数字或换行符.然后,ruby切换回irb的线程,该线程将编写提示并等待输入.
In your example, each time you press enter, the thread gets a split second to execute--enough time to write out a number or a newline. Then ruby switches back to irb's thread, which writes the prompt and waits on input.
*使用JRuby,IronRuby和Rubinius 2.0,可以同时运行多个线程.
* With JRuby, IronRuby, and Rubinius 2.0, multiple threads can run at the same time.
我在Windows上进行了测试,线程在那里继续运行.如果希望线程在Mac上继续运行,可以将其另存为sirb.rb(简单的irb),然后使用它代替irb:
I tested on Windows, and threads keep running there. If you want threads to keep running on Mac, you could save this as, say, sirb.rb (simple irb) and use it instead of irb:
$stdout.sync = true
while true
print "> "
p(eval gets)
end
请注意,与irb不同,它不支持跨多行的语句,也不支持移动插入记号以进行编辑或按Up(向上)以获取历史记录(在Mac OS X上).示例:
Note that, unlike irb, it doesn't support a statement spanning multiple lines, nor does it support moving the caret to edit or pressing Up for history (on Mac OS X). Example:
> for i in 1..10; print i ** 2, " "; end; puts
1 4 9 16 25 36 49 64 81 100
nil
这篇关于为什么在线程中使用puts方法时会表现出奇怪的现象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!