mpotma
mpotma

Reputation: 243

How do I throw an exception to a specific thread in Python?

I'm trying to create a timeout, where if a function doesn't finish execution in time, a default value is returned. What I have below seems like it would work, except that the KeyboardInterrupt exception is raised in the main thread, whereas my callback function is in a separate thread.

Is there any way in Python of specifying which thread the exception is raised in?

def interrupt():
    raise KeyboardInterrupt

def callback_function():
    # Start 16 ms timer
    timer = threading.Timer(0.016, interrupt)
    timer.start()
    try:
        result = inconsistent_execution_time_function(data)
        timer.cancel()
    except KeyboardInterrupt:
        print("Long execution time")
        result = default
    return result

Upvotes: 0

Views: 950

Answers (1)

Kurtis Rader
Kurtis Rader

Reputation: 7459

As you surmised your solution doesn't work because threading.Timer() is implemented using a separate thread (not the main thread) and thus can't propagate an exception to the original thread. Your approach won't work.

The usual solution is to employ a cooperative approach. Create a context object, possibly using thread local storage. That context object starts out with the boolean representing whether a timeout occurred set to false. Your interrupt() function sets that var to true. Your inconsistent_execution_time_function() then periodically checks whether the var is true.

But if you absolutely want to send a signal, possibly to interrupt a long running syscall, you should use signal.pthread_kill() in your timer function. Obviously you will need to send the thread ID of your callback_function() to that function by adding an appropriate parameter to its definition and add a args=(threading.ident) parameter to the threading.Timer() call.

Upvotes: 1

Related Questions