How to interrupt (not kill) julia from the REPL (again)?

Instead of adding a question to the old thread

from 2019 of almost the same title, I create a new Topic.

From the old thread, I learned that Ctrl-C doesn’t always work, for example, during I/O. So, my question is, how to specify the points where Ctrl-C is accepted?

while until_done
   # . . . Some julia code without I/O . . . 
   # . . . If you must interrupt, you want to interrupt here. . . .
   func_doing_intensive_io()
   # . . . You want to allow interruption here, too . . .
end

I run a program like this on the REPL but I’ve never succeeded to interrupt it, perhaps because the program spends 99% of the time in I/O.

I tried something like this:

try
while until_done
   # . . . Some julia code without I/O . . . 
   func_doing_intensive_io()
   sleep(2)
   # . . . . . .
end
catch e
   display(e)
   exit(1)
end

This one isn’t interruptible either. If sleep() is interruptible, the above code should work, I thought.

How are signals handled on REPL? Is there a mechanism like trap of Unix shells?

1 Like

Both sleep and print seems to be easily interruptable for me, do you have a more specific example that doesn’t work for you?

julia> for i in 1:10
       sleep(1)
       end
^CERROR: InterruptException:
Stacktrace:
 [1-6] ⋮ internal
     @ Base, Unknown
   [7] sleep
     @ ./asyncevent.jl:240 [inlined]
   [8] top-level scope
     @ ./REPL[1]:2
Use `err` to retrieve the full stack trace.

julia> while true
       print("\rHello")
       end
HelloERROR: InterruptException:
Stacktrace:
 [1-6] ⋮ internal
     @ Base, Unknown
   [7] print(xs::String)
     @ Base ./coreio.jl:3
   [8] top-level scope
     @ ./REPL[2]:2
Use `err` to retrieve the full stack trace.
1 Like

Thanks! You are right. In the following example, I confirm that.

do you have a more specific example that doesn’t work for you?

Yes, I’ve successfully stripped my program down so that it clearly demonstrates my problem:

using Plots

function plot_slp()
  xax = -10:0.1:10
  display(plot(xax, sin.(xax)))
end

try
for t in 1:4
  plot_slp() # <- Comment out and the program is interruptible
  print("sleeping . . . "); flush(stdout)
  sleep(3)
  println("wake up."); flush(stdout)
end
catch e
  display(e)
end
  1. Launch the REPL on a terminal window.
  2. include("this-sample-program.jl")
  3. Type Ctrl-C. (Make sure the signal is sent to the terminal, by clicking on it.) Doesn’t work.
  4. On a text editor, comment out the plotting function.
  5. include("this-sample-program.jl") on the julia prompt.
  6. Ctrl-C doesn’t work.
  7. Quit the window showing the plot.
  8. include("this-sample-program.jl")
  9. Now the program is interruptible.

That suggests that the presence of the plot window is blocking the interruption.

So, a workaround is: During the sleep, quit the plot window and then type Ctrl-C on the terminal. I’ve confirmed that this workaround works.

Well, we need a complete signal handling mechanism as in C and shells.

Yeah, seems inconsistent there. If I do Ctrl-C x 2 it stops, though I don’t really see why that should be needed. Maybe something with threads and the gui that affect it?

1 Like

If I do Ctrl-C x 2 it stops

Which operating system are you on? I can never ever interrupt my program however many times I press Ctrl-C, as long as the plotting window is there.

I’m on macOS 13.4. I run the julia REPL on iTerm2, if that matters.

I tried it on wsl.

For a test, I just launched the julia REPL and sent SIGTERM to the julia REPL process, issuing kill -INT <process id> from another terminal. Then the julia REPL reported InterruptException and quitted.

I launched the julia REPL again and typed Ctrl+C but it didn’t quit. It just displayed “^C” at its prompt.

So, although I understand very little, I guess it’s julia’s command line which decides what to do with the key stroke Ctrl+C and somehow it doesn’t generate an exception when a plotting window (gksqt) exists. (For a normal shell prompt, it’s the tty facility which translates the key stroke to the INT signal.)