Julia, handle keyboard interrupt
Asked Answered
M

3

8

Title says it all. How can I handle or catch a SIGINT in julia? From the docs I assumed I just wanted to catch InterruptException using a try/catch block like the following

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

But I never enter the catch block when I kill the program with ^C.

edit: The code above works as expected from the julia REPL, just not in a script.

Mcdevitt answered 29/12, 2013 at 23:32 Comment(0)
S
9

I see the same behavior as alto, namely that SIGINT kills the entire process when my code is run as a script but that it is caught as an error when run in the REPL. My version is quite up to date and looks rather similar to that of 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

Digging through the source, I found hints that Julia's interrupt behavior is determined by an jl_exit_on_sigint option, which can be set via a ccall. jl_exit_on_sigint is 0 for the REPL, but it looks as if init.c sets it to 1 when running a Julia program file from the command line.

Adding the appropriate ccall makes alto's code works regardless of the calling environment:

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

This does seem to be a bit of a hack. Is there a more elegant way of selecting the interrupt behavior of the environment? The default seems quite sensible, but perhaps there should be a command line option to override it.

Songwriter answered 26/3, 2015 at 3:4 Comment(1)
Void has been renamed to Nothing.System
Z
2

For julia >= 1.5, there is Base.exit_on_sigint. From the docs (retrieved on 20220419)

Set exit_on_sigint flag of the julia runtime. If false, Ctrl-C (SIGINT) is capturable as InterruptException in try block. This is the default behavior in REPL, any code run via -e and -E and in Julia script run with -i option.

Zoi answered 19/4, 2022 at 21:51 Comment(0)
L
0

Works for me. I'm running

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

but I expect it's not necessary to be fully up-to-date for this to work (I'd guess 0.2 should be fine too).

Leveroni answered 31/12, 2013 at 11:30 Comment(1)
I'm on 0.3.0-prerelease+459. After you said it worked I went back and tested again. It works in the REPL, but not if I put the code in a .jl file and call it like $ julia somefile.jlMcdevitt

© 2022 - 2024 — McMap. All rights reserved.