Phr*_*ogz 5 ruby console multithreading
对于这个答案,我编写了如下代码:
def show_wait_spinner
dirty = false
spinner = Thread.new{
loop{
print "*"
dirty = true
sleep 0.1
print "\b"
dirty = false
}
}
yield
spinner.kill
print "\b" if dirty
end
print "A"
show_wait_spinner{ sleep rand }
puts "B"
Run Code Online (Sandbox Code Playgroud)
目的是确保最终输出为"AB"— "\b"如果线程尚未打印最终结果,则将其打印出来。在begin/rescue/ensure存在的Ruby中,该代码对我来说似乎很混乱。所以我尝试了其他的实现show_wait_spinner; 它们都无法确保"AB"始终是输出,从不"A*B"或"AB*"。
有没有更干净,更像Ruby的方式来实现此逻辑?
def show_wait_spinner
stop = false
stopm = Mutex.new
spinner = Thread.new{
loop{
print "*"
sleep 0.1
print "\b"
stopm.synchronize{ break if stop }
}
}
yield
stopm.synchronize{ stop = true }
STDOUT.flush
end
Run Code Online (Sandbox Code Playgroud)
…但是我的逻辑必须关闭,因为这总是导致“ A * B”。
第二次尝试导致有时打印“ A * B”,有时打印“ AB”:
def show_wait_spinner
stop = false
spinner = Thread.new{
Thread.current[:stop] = false
loop{
print "*"
sleep 0.1
print "\b"
stopm.synchronize{ break if Thread.current[:stop] }
}
}
yield
spinner[:stop] = true
STDOUT.flush
end
Run Code Online (Sandbox Code Playgroud)
def show_wait_spinner
spinner = Thread.new{
dirty = false
begin
loop{
print "*"
dirty = true
sleep 0.1
print "\b"
dirty = false
}
ensure
print "\b" if dirty
end
}
yield
spinner.kill
STDOUT.flush
end
Run Code Online (Sandbox Code Playgroud)
def show_wait_spinner
spinner = Thread.new{
dirty = false
begin
loop{
print "*"
dirty = true
sleep 0.1
print "\b"
dirty = false
}
rescue
puts "YAY"
print "\b" if dirty
end
}
yield
spinner.raise
STDOUT.flush
end
Run Code Online (Sandbox Code Playgroud)
为什么不杀死线程,为什么不翻转一个导致它在预定点停止的变量?如果让它循环通过并在循环结束时退出,您将没有那么多麻烦。
例如:
def show_wait_spinner
running = true
spinner = Thread.new do
while (running) do
print "*"
sleep 0.1
print "\b"
end
end
yield
running = false
spinner.join
end
print "A"
show_wait_spinner{ sleep rand }
puts "B"
Run Code Online (Sandbox Code Playgroud)
当您打电话时,Thread#kill您不知道线程在哪里,并且线程没有机会清理它在做什么。如果不遵守您的礼节性的“停止运行”请求,则始终可以终止线程。
在互斥锁示例中,您需要等待线程完成才能退出该方法。当前您设置stop为 true,然后退出该方法,B在微调器线程能够唤醒并打印最后一个退格键以删除字符之前打印并结束脚本*。
另外,breakinstopm.synchronize{ break if stop }只退出内部块,而不退出循环,所以你需要使用catch/throw什么的。
但是,您不需要互斥体。这在 1.9.3 中对我有用:
def show_wait_spinner
exit = false
spinner = Thread.new{
loop{
print "*"
sleep 0.1
print "\b"
break if exit
}
}
yield
exit = true
spinner.join
end
Run Code Online (Sandbox Code Playgroud)
$stdout.sync = true在顶部添加使其可以在 1.8.7 中运行。
| 归档时间: |
|
| 查看次数: |
4350 次 |
| 最近记录: |