我在Julia中有一段代码,其中求解器在寻求解决非常复杂的问题时会迭代很多次。目前,我必须为代码提供一些迭代次数,设置得足够低,以至于我不必等待数小时才停止代码以保存当前状态,但是足够高以至于我没有必须每隔5分钟继续激活代码。
有没有一种方法,使用Julia(0.2)的当前状态,检测一个键击指示代码结束而不保存(如果出现问题)或以保存结束?我需要一个方法,这样代码将继续不受阻碍,除非发生这样的击键事件,并且会在任何迭代时中断。
基本上,我正在寻找一个命令,如果发生了击键(在Julia运行的终端有焦点的情况下),它将在击键时读取,并且如果击键是特定键,则运行某些代码。这可能吗?
注意:我正在Xubuntu上通过xfce4-terminal运行julia,以防影响所需的命令。
答案 0 :(得分:3)
你可以从异步任务中读取STDIN,阻塞直到有东西可供读取。在主计算任务中,当您准备检查输入时,可以调用yield()为读取任务提供几个周期,并检查全局以查看是否有任何内容被读取。例如:
input = ""
@async while true
global input = readavailable(STDIN)
end
for i = 1:10^6 # some long-running computation
if isempty(input)
yield()
else
println("GOT INPUT: ", input)
global input = ""
end
# do some other work here
end
请注意,由于这是合作多线程,因此没有竞争条件。
答案 1 :(得分:1)
您可以通过发送中断(Ctrl+C
)来实现此目的。这应该可以在REPL中使用而不需要对代码进行任何更改 - 如果要实现保存,则必须处理生成的InterruptException
并提示用户。
答案 2 :(得分:0)
我对来自steven-g-johnson的回答感到有些麻烦,最终使用Channel
在任务之间进行通信:
function kbtest()
# allow 'q' pressed on the keyboard to break the loop
quitChannel = Channel(10)
@async while true
kb_input = readline(STDIN)
if contains(lowercase(kb_input), "q")
put!(quitChannel, 1)
break
end
end
start_time = time()
while (time() - start_time) < 10
if isready(quitChannel)
break
end
println("in loop @ $(time() - start_time)")
sleep(1)
end
println("out of loop @ $(time() - start_time)")
end
这需要先按然后按,这样可以很好地满足我的需求。