【问题标题】:Is resetting Python thread/process tasks by calling self.run() pythonic?是否通过调用 self.run() pythonic 来重置 Python 线程/进程任务?
【发布时间】:2018-03-21 20:58:07
【问题描述】:

关于进程类 MyProcessClass 下面的代码,有时我想重新运行所有 self.run 任务。

self.run(retry=True) 是我用来在类中重新运行 run(self) 任务的方法。它允许我在任何时候从任何我想从任何类函数中重新运行流程类 run(self) 的任务。


MyProcessClass(Process):
     def __init__(self):
          Process.__init__(self)

     #gets called automatically on class initialization 
     #process.start().
     #it also gets called when a class function calls 
     #self.run(retry=True)
     def run(self,end=False,retry=False):
          if end==True:
             sys.exit()
          elif retry==True:
              redo_prep()
          do_stuff()

     #represents class functions doing stuff
     def do_stuff():
         #stuff happens well
         return
         #stuff happens and need to redo everything
         self.run(retry=True)

我不希望线程/进程结束,但我希望一切都重新运行。这是否会导致问题,因为 run 函数被递归调用,并且我一次运行数百个这样的进程类对象。全部运行时,该盒子的内存约为 32GB。只有需要的对象才会重新运行。

我的目标是在需要时重新运行 self.run 任务,或者在需要时从类中的任何位置结束线程,无论是 16 个深度函数还是 2 个函数。从某种意义上说,我正在重置线程的任务,因为我知道重置内部的线程不起作用。我从How to close a thread from within? 看到了有关“重置”线程的其他想法。我正在寻找处理重新运行类 self.run 任务的最 Pythonic 方式。

我通常在课堂上使用 try-catch:

  def function():
     while True:
       try:
         #something bad
       except Exception as e:
         #if throttle just wait
         #otherwise, raise
       else:
         return

附加问题:如果我要引发自定义异常以触发重试模块的@retry,我是否必须重新引发?与上面的示例相比,这或多或少是 Python 的吗?

我的脚本以一种我以前从未见过的方式出现了问题,我担心调用 self.run(retry=True) 会导致它这样做。我想看看我在进程类中调用 self.run() 的方式是否有什么疯狂之处。

【问题讨论】:

  • 考虑使用retrying 模块。
  • 这绝对激发了我的兴趣,并帮助我更多地了解我可能需要做的事情 - 所以我很感激帮助,但我不明白如何从 try-catch 中调用它没有它处理它而不是@retry。这就是为什么我不再将整个事物包装在 try catch 中,而是定义特殊的错误异常类,如 RetryThread。它最终没有被最外层的 try-catch 捕获。
  • retrying 模块应该涵盖您的用例。您认为使用retrying 有什么障碍?考虑到您可以创建自己的自定义异常并以巧妙的方式处理它们(IE 以特定方式引发错误以了解需要什么错误处理)——我建议不要尝试发明复杂的重试逻辑,因为它应该是易于委托给retrying。我认为你遇到的问题是可以克服的。仔细想想你的问题。你能解释一下为什么你认为这种方法是必要的吗?如果是这样,请考虑使用这些细节更新您的问题。
  • 好的。我开始看到光明。我是否只是在 try-catch 中重新引发自定义异常?我担心这会更加复杂,因为我将在整个课堂上使用 try-catch 并且除非我重新引发自定义异常,否则 @retry(specialexception) 不会被击中。你建议这是我应该如何处理这个问题吗?我上面提到的方法比这更容易吗?我想我真的很喜欢重试,但担心必须在我的 try-catch 中重新引发这个特殊异常是不行的。我想确保它是pythonic。我编辑了问题来说明这一点。
  • 我会考虑您的设计以及您的尝试/例外发生的位置以及您遇到的具体错误。调用带有@retry 修饰的函数不会被该修饰函数之外的try/except 捕获,并且重试逻辑将按预期工作。我不确定你认为你的问题是什么,我的猜测是你误解了 try/except 如何影响重试——试着把一些简单的例子放在一起并测试它是如何工作的。如果需要进行任何重组,那应该是微不足道的。请记住,简单胜于复杂。不要想太多。

标签: python multithreading multiprocessing


【解决方案1】:

看起来您正在实现一个基本的重试场景。为此,您应该考虑将其委托给一个库,例如retrying。与您尝试在线程中实现以“重置”它的逻辑相比,这可能是一种更好的方法。

通过引发/重试特定异常,您应该能够使用retrying 干净利落地实现正确的错误处理逻辑。作为最佳实践,您应该避免广泛的异常并尽可能捕获特定异常。

考虑一种模式,线程本身不需要知道它是否需要“重置”或重新启动。相反,如果可能,请尝试让您的线程返回一些值或异常信息,以便主线程可以决定是否重新排队任务。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-09
    相关资源
    最近更新 更多