gpt4 book ai didi

ruby - 停止线程,确保某些最终代码运行

转载 作者:数据小太阳 更新时间:2023-10-29 07:25:05 26 4
gpt4 key购买 nike

对于 this answer我写了这样的代码:

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"

目标是确保最终输出为"AB" — 打印最终 "\b"如果它还没有被线程打印出来。该代码在 Ruby 中对我来说似乎很乱 begin/rescue/ensure存在。所以我尝试了 show_wait_spinner 的一些其他实现;所有这些都无法确保 "AB"始终是输出,而不是 "A*B""AB*" .

是否有更简洁、更像 Ruby 的方式来实现此逻辑?

通过 Mutex 在循环结束时停止

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

...但我的逻辑一定是错误的,因为这总是导致“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

杀死并确保线程

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

提出并拯救话题

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

最佳答案

为什么不翻转一个变量,使其在预定义的点停止,而不是终止您的线程?如果你让它循环并在循环结束时退出,你几乎不会遇到那么多麻烦。

例如:

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"

当您调用 Thread#kill 时,您不知道线程在哪里,并且线程没有机会清理它正在做的事情。如果不尊重您礼貌的“停止运行”请求,您可以随时终止线程。

关于ruby - 停止线程,确保某些最终代码运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10263497/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com