"kill" internal execution

Is it possible to “kill” the execution of a function under some condition?

The use case here would be for benchmarking. That is, I want to run several benchmarks, but I don’t want any of them to take more than some ammount of time, for example 1 minute. What I would like to do is to stop the execution of the function when that time is reached, without having to modify the internals of the function. Like a programmatically Control-C with exception handling.

Anything like that is possible?

(by the way, if someone knows if that is possible in Python, I’m comparing with some python stuff and that would be useful there as well).

1 Like

If you spawn each run in their own task, you can do Base.throwto(t::Task, InterruptException()), which is what Ctrl-C actually does.

3 Likes

For the records, this is how it works:

julia> function kill_at_max(fun, tmax)
           tsk = @task fun()
           schedule(tsk)
           t = 0
           while t < tmax
               t += 1
               sleep(1)
               if istaskdone(tsk)
                  return true
               end
           end
           try 
              Base.throwto(tsk, InterruptException())
           catch
           end
           return false
       end
kill_at_max (generic function with 1 method)

julia> wait() = sleep(3)
wait (generic function with 1 method)

julia> kill_at_max(wait, 4)
true

julia> kill_at_max(wait, 2)
false

You can’t use throwto or schedule(_, exception; error = true) on an arbitrary task that is already started Stop/terminate a (sub)task started with @async - #5 by jameson.

If you are curious, see https://github.com/JuliaLang/julia/pull/41270 for exactly when schedule can be called on a task that is already started. But I don’t think it’d be useful for the use case mentioned in the OP.

Probably the only way to do this reliably is to do the benchmark in a child process. (Or use something like Cassette to inject the cancellation token; but it’d change the program that is benchmarked.)

2 Likes

Yeah… maybe it is not worth the effort, I will try to keep the benchmark more mundane :slight_smile: