Reputation: 1525
I have a function a
doing some tasks and another function b
being a callback to some events. Whenever an event happens, function b
is called and I would like to make it able to interrupt the execution of function a
. Both functions are declared inside the same class.
Function a
is not supposed to call function b
. Function b
is totally independent, it is a callback to an external event like "user face detected" coming from ROS: robot operating system.
what I need is basically something like Ctrl+C that can be called from within Python and which only aborts a targeted function and not the whole program.
Can this be done in Python?
Upvotes: 13
Views: 27463
Reputation: 2082
It's generally recommended not to use exception calling for flow-control. Instead, look to python stdlib's threading.Event
, even if you only plan on using a single thread (even the most basic Python program uses at least one thread).
This answer https://stackoverflow.com/a/46346184/914778 has a good explanation of how calling one function (function b) could interrupt another (function a).
Here's a few important parts, summarized from that other answer.
Set up your threading libraries:
from threading import Event
global exit
exit = Event()
This is a good replacement for time.sleep(60)
, as it can be interrupt:
exit.wait(60)
This code will execute, until you change exit to "set":
while not exit.is_set():
do_a_thing()
This will cause exit.wait(60)
to stop waiting, and exit.is_set()
will return True
:
exit.set()
This will enable execution again, and exit.is_set()
will return False
:
exit.clear()
Upvotes: 8
Reputation: 986
I had done using Threading.
import threading
class myThread (threading.Thread):
def __init__(self, threadID, name, counter):
threading.Thread.__init__(self)
self.threadID = threadID
self.name = name
self.counter = counter
def run(self):
# Get lock to synchronize threads
#threadLock.acquire()
if self.name == 'a':
function_a(self.name, self.counter, 3)
if self.name == 'b':
function_b(self.name, self.counter, 3)
def function_a(threadName, delay, counter):
name = raw_input("Name")
print name
def function_b(threadName, delay, counter):
global thread1
thread1.shutdown = True
thread1._Thread__stop()
# Create new threads
thread1 = myThread(1, "a", 0)
thread2 = myThread(2, "b", 0)
# Start new Threads
thread1.start()
thread2.start()
function_a stopped executing when thread1 is stopped
Upvotes: 0
Reputation: 31777
I would do the following:
Here's some pseudo-code:
class InterruptExecution (Exception):
pass
def function_a():
while some_condition_is_true():
do_something()
if callback_time():
try:
function_b()
except InterruptExecution:
break
do_something_else()
do_final_stuff()
def function_b():
do_this_and_that()
if interruption_needed():
raise (InterruptExecution('Stop the damn thing'))
Upvotes: 5