【问题标题】:Threading with Bottle.py Server使用 Bottle.py 服务器进行线程化
【发布时间】:2015-09-24 22:14:56
【问题描述】:

我遇到了一个线程问题,我尝试过的任何方法都无法解决。我也在 StackOverflow 中搜索过,但我只能找到不适用于我的案例,或者我不理解的解释。

我正在尝试使用 BottlePy 构建一个应用,而我想要的功能之一需要一个在后台运行的函数。为此,我试图让它在一个线程中运行。但是,当我启动线程时,它会运行 两次

我在某些地方读到,可以使用 if __name__ == '__main__': 检查函数是在主脚本中还是在模块中,但是我无法做到这一点,因为 __name__ 总是返回模块的名称。

下面是我现在正在做的一个例子。

主脚本:

# main.py
from MyClass import *
from bottle import *

arg = something

myObject = Myclass(arg1)

app = Bottle()
app.run('''bottle args''')

班级:

# MyClass.py
import threading
import time

class MyClass:
    def check_list(self, theList, arg1):
        a_list = something()
        time.sleep(5)
        self.check_list(a_list, arg1)

    def __init__(self, arg1):
        if __name__ == '__main__':
            self.a_list = arg.returnAList()
            t = threading.Thread(target=self.check_list, args=(a_list, arg1))

所以我在这里打算让 check_list 一直在一个线程中运行,做一些事情并等待几秒钟再次运行。所有这些都是为了让我可以更新列表,并能够使用主脚本阅读它。

你能解释一下我做错了什么,为什么线程运行两次,我该如何避免这种情况?

【问题讨论】:

  • 您正在check_list 中创建第二个线程?如果删除 time.sleep(5) 和后面的行会怎样?另外,您不需要输入if __name__ ...,至少这里不需要。
  • 既然你提到了它......是的,这似乎不对。但是,即使没有在函数末尾创建新线程,它也会被调用两次。如果我只是做 'self.check_time(plans, db_handler)' 它仍然不能按预期工作。
  • 在您编辑的代码中,您有check_list 调用check_list,错字?
  • 它应该被再次调用,不是吗?否则它将如何每 x 秒运行一次?之前是创建线程的,现在直接调用,不创建线程。
  • 您可以通过在__init__ 的开头调用traceback.print_stack() 来了解是否在两个地方调用了__init__。如果你得到两个不同的堆栈跟踪,你现在知道它在哪里被调用了两次。如果你只得到一个,那么你创建和运行线程的方式一定有问题。如果您两次获得相同的结果,则可能是某些原因导致您的 main.py 运行两次。

标签: python multithreading bottle


【解决方案1】:

感谢用户 Weeble 的评论,找出了问题所在。当他说'某事导致你的 main.py 运行两次'时,我记得 Bottle 有一个名为“reloader”的参数。当设置为 True 时,这将使应用程序加载两次,因此线程创建也会运行两次。

【讨论】:

    【解决方案2】:

    这很好用:

    import threading
    import time
    
    class MyClass:
        def check_list(self, theList, arg1):
            keep_going=True
            while keep_going:
                print("check list")
                #do stuff
                time.sleep(1)
    
        def __init__(self, arg1):
            self.a_list = ["1","2"]
            t = threading.Thread(target=self.check_list, args=(self.a_list, arg1))
            t.start()
    
    myObject = MyClass("something")
    

    【讨论】:

    • 现在如果我想从 main 调用它怎么办?我做 myObject = MyClass(arg1),是吗?
    • 这正是我所做的,是的。但是如果你正在运行一个应用程序,最好在应用程序的__init__ 方法中调用它(但我真的不知道Bottle 是如何工作的)
    猜你喜欢
    • 1970-01-01
    • 2015-04-11
    • 1970-01-01
    • 2011-03-18
    • 1970-01-01
    • 2014-09-22
    • 2020-05-18
    • 2010-12-16
    • 2017-04-10
    相关资源
    最近更新 更多