【问题标题】:Interrupt function execution from another function in Python从 Python 中的另一个函数中断函数执行
【发布时间】:2014-07-30 05:40:41
【问题描述】:

我有一个函数a 执行一些任务,另一个函数b 是一些事件的回调。每当发生事件时,都会调用函数b,我想让它能够中断函数a的执行。这两个函数都在同一个类中声明。

函数a 不应该调用函数b。函数b是完全独立的,它是对来自ROS:机器人操作系统的“检测到用户面部”等外部事件的回调。

我需要的基本上是可以从 Python 中调用的 Ctrl+C 之类的东西,它只会中止目标函数而不是整个程序。

这可以在 Python 中完成吗?

【问题讨论】:

  • 你的回调是怎么调用的?
  • 我正在使用 ROS(机器人操作系统),您可以在其中订阅某些事件的任何功能。
  • 这样的??? chk = True def function_a(): if chk: do_process() def function_b(): global chk chk = False
  • 是的,我考虑过这一点,但是我需要在脚本 do_process 的每个块上加上 if chk,这样程序即使在 do_process() 期间也可以退出,而不是在它完成后退出。
  • 使用线程怎么样?你试过了吗?

标签: python interrupt


【解决方案1】:

一般不建议使用异常调用来进行流控。相反,请查看 python stdlib 的threading.Event,即使您只打算使用单个线程(即使是最基本的 Python 程序也至少使用一个线程)。

https://stackoverflow.com/a/46346184/914778 这个答案很好地解释了调用一个函数(函数 b)如何中断另一个函数(函数 a)。

这是从其他答案中总结的一些重要部分。

设置你的线程库:

from threading import Event
global exit
exit = Event()

这是time.sleep(60) 的一个很好的替代品,因为它可以被中断:

exit.wait(60)

此代码将执行,直到您将 exit 更改为“set”:

while not exit.is_set():
    do_a_thing()

这将导致exit.wait(60) 停止等待,exit.is_set() 将返回True

exit.set()

这将再次启用执行,exit.is_set() 将返回 False

exit.clear()

【讨论】:

    【解决方案2】:

    我会做以下事情:

    • 定义自定义异常
    • 在适当的 try/catch 块中调用回调函数
    • 如果回调函数决定中断执行,它将引发异常,调用者将捕获它并根据需要进行处理。

    这是一些伪代码:

    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'))
    

    【讨论】:

    • 感谢您的快速回答,不幸的是,在我最初的问题中滥用“回调”一词导致了误解。函数 a 不调用函数 b。函数 b 应该能够从外部中断函数 a。
    【解决方案3】:

    我已经使用线程。

        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 在 thread1 停止时停止执行

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-05
      • 2017-12-19
      • 2011-12-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多