我需要编写一个运行两个线程的简单应用程序:
- 线程 1:按定时运行,假设每 1 分钟运行一次
- 线程 2:只是一个执行“操作”的“正常”while True 循环
如果不是按定时间隔运行的要求,我根本不会考虑扭曲,但简单的 sleep(60) 还不够好,构造如下:
l = task.LoopingCall(timed_thread)
l.start(60.0)
reactor.run()
看起来很简单就能实现我想要的目标。
现在,我如何“正确”添加另一个线程?
我在这里看到两个选择:
- 使用线程库并运行两个“python 线程”,一个执行我的 while 循环,另一个运行reactor.run()。但谷歌似乎反对这种方法并建议使用扭曲线程
- 使用绞线。这就是我尝试过的,但不知怎的,这对我来说看起来有点笨拙。
这是我想出的:
def timed_thread():
print 'i will be called every 1 minute'
return
def normal_thread():
print 'this is a normal thread'
time.sleep(30)
return
l = task.LoopingCall(timed_thread)
l.start(60.0)
reactor.callInThread(normal_thread)
reactor.run()
这似乎有效,但是!我无法停止该应用程序。如果我按 ^C 它不会执行任何操作(如果没有“callInThread”,它只会像您期望的那样停止)。 ^Z 轰炸到 shell,如果我然后执行“kill %1”,它似乎会杀死该进程(shell 报告这一点),但“正常”线程继续运行。 kill PID 并不能消除它,唯一的解决办法是kill -9。真的很奇怪。
所以。我究竟做错了什么?在twisted中实现两个线程是正确的方法吗?我不应该为扭曲而烦恼吗?还有哪些其他“标准”替代方案可以实现定时调用? (“标准”我的意思是我可以 easy_install 或 yum 安装它们,我不想开始从随机网页下载和使用一些随机脚本)。
您没有解释为什么这里实际上需要线程。如果你有的话,我也许能够解释为什么你don't需要他们。 ;)
除此之外,我可以确认你对事物的基本理解是正确的。不过,我可以澄清的一个可能的误解是“python 线程”和“Twisted 线程”完全不同的概念。他们不是。 Python提供了一个线程库。 Twisted 的所有线程 API 都是根据 Python 线程库实现的。只是API不同。
就关闭而言,您有两种选择。
- 直接使用 Python 的线程 API 启动永远运行的线程,并使该线程成为守护进程。即使守护线程仍在运行,您的进程也可以退出。此解决方案可能存在的问题是,某些版本的 Python 存在守护线程问题,这会导致关闭时崩溃。
- 使用 Twisted 的 API 或 stdlib 线程 API 创建线程,还可以使用以下命令添加 Twisted 关闭挂钩
reactor.addSystemEventTrigger('before', 'shutdown', f)
。在该钩子中,与工作线程通信并告诉它关闭。例如,您可以共享一个threading.Event
在扭曲线和工作线之间并有钩子set
它。工作线程可以定期检查它是否已设置,并在发现已设置时退出。除了不崩溃之外,这还比守护线程有另一个优势 - 它允许您在进程退出之前在工作线程中运行一些清理或终结代码。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)