朱莉娅,处理键盘中断。

7

标题已经说得很清楚了。我该如何在julia中处理或捕捉 SIGINT 信号?从文档中,我认为我只需要使用 try/catch 块来捕获 InterruptException 就可以了,像下面这样:

try
    while true
        println("go go go")
    end
catch ex
    println("caught something")
    if isa(ex, InterruptException)
        println("it was an interrupt")
    end
end

但是当我使用^C结束程序时,我从未进入捕获块。

编辑:上面的代码在julia REPL中按预期工作,但在脚本中不起作用。

3个回答

9

我看到的行为与Alto相同,即当我的代码作为脚本运行时,SIGINT会结束整个进程,但在REPL中运行时会被捕获为错误。我的版本非常新,看起来与tholy的版本相似:

julia> versioninfo()
Julia Version 0.3.7
Commit cb9bcae* (2015-03-23 21:36 UTC)
Platform Info:
  System: Linux (x86_64-linux-gnu)
  CPU: Intel(R) Core(TM) i7-3610QM CPU @ 2.30GHz
  WORD_SIZE: 64
  BLAS: libopenblas (DYNAMIC_ARCH NO_AFFINITY Sandybridge)
  LAPACK: libopenblas
  LIBM: libopenlibm
  LLVM: libLLVM-3.3

通过查看源代码,我发现 Julia 的中断行为由一个名为 jl_exit_on_sigint 的选项决定,可以通过 ccall 进行设置。对于 REPL 来说,jl_exit_on_sigint 的值为 0,但是在从命令行运行 Julia 程序文件时,init.c 会将其设置为 1
添加适当的 ccall 可以使 Alto 的代码在任何调用环境下都能正常工作。
ccall(:jl_exit_on_sigint, Void, (Cint,), 0)

try
    while true
        println("go go go")
    end
catch ex
    println("caught something")
    if isa(ex, InterruptException)
        println("it was an interrupt")
    end
end

这似乎有些繁琐。有没有更优雅的方法来选择环境中的中断行为?默认设置似乎很合理,但也许应该有一个命令行选项来覆盖它。


1
"Void"已被更名为"Nothing"。 - nalply

1
对于 Julia 版本大于等于 1.5,有 Base.exit_on_sigint。根据文档(于20220419检索):
设置 Julia 运行时的 exit_on_sigint 标志。如果为 false,则可以在 try 块中捕获 Ctrl-C(SIGINT)作为 InterruptException。这是 REPL 中的默认行为,也适用于通过 -e 和 -E 运行的任何代码以及使用 -i 选项运行的 Julia 脚本。

0

对我来说有效。我正在运行

julia> versioninfo()
Julia Version 0.3.0-prerelease+695
Commit 47915f3* (2013-12-27 05:27 UTC)
DEBUG build
Platform Info:
  System: Linux (x86_64-linux-gnu)
  CPU: Intel(R) Core(TM) i7 CPU       L 640  @ 2.13GHz
  WORD_SIZE: 64
  BLAS: libopenblas (USE64BITINT DYNAMIC_ARCH NO_AFFINITY)
  LAPACK: libopenblas
  LIBM: libopenlibm

但我认为这并不是必须的,只要版本不太旧就可以(我猜0.2也应该可以)。


1
我现在使用的是0.3.0-prerelease+459版本。在你说过它可以工作之后,我又进行了一次测试。虽然在REPL中可以工作,但如果我将代码放到.jl文件中,并像这样调用$ julia somefile.jl,则无法工作。 - alto

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接