我需要编写一个运行两个线程的简单应用程序: - 线程1:在定时时段运行,假设每1分钟一次 - 线程2:只是一个'正常'而真正的循环'做'东西'
如果没有按时间间隔运行的要求我根本不会看到扭曲,但是简单的睡眠(60)不够好并且构造如下:
l = task.LoopingCall(timed_thread)
l.start(60.0)
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,如果我然后'杀死%1'它似乎杀死进程(shell报告),但'正常'线程继续运行。杀死PID不会摆脱它,唯一的治疗方法是杀死-9。真奇怪。
因此。我究竟做错了什么?在扭曲中实现两个线程是否正确?我不应该打扰吗?还有哪些“标准”替代方案可以实现定时呼叫? ('标准'我的意思是我可以easy_install或yum安装它们,我不想开始下载并使用随机网页中的一些随机脚本)。
答案 0 :(得分:5)
你没有在这里解释为什么你真的需要线程。如果你有,我可能已经能够解释为什么你不需要它们。 ;)
除此之外,我可以确认您对事物的基本理解是正确的。但是,我可以理解的一个可能的误解是“python线程”和“扭曲线程”彼此不同的概念。他们不是。 Python提供了一个线程库。所有Twisted的线程API都是根据Python的线程库实现的。只有API不同。
关于关机,你有两个选择。
reactor.addSystemEventTrigger('before', 'shutdown', f)
添加Twisted关闭钩子。在该钩子中,与工作线程通信并告诉它关闭。例如,您可以在Twisted线程和工作线程之间共享threading.Event
并使用钩子set
。工作线程可以定期检查它是否已经设置,并在它注意到它时已经退出。除了不崩溃之外,这还提供了另一个优于守护程序线程的优势 - 它允许您在进程退出之前在工作线程中运行一些清理或终结代码。答案 1 :(得分:2)
假设你的主要是相对无阻塞的:
import random
from twisted.internet import task
class MyProcess:
def __init__(self):
self.stats = []
self.lp = None
def myloopingCall(self):
print "I have %s stats" % len(self.stats)
def myMainFunction(self,reactor):
self.stats.append(random.random())
reactor.callLater(0,self.myMainFunction,reactor)
def start(self,reactor):
self.lp = task.LoopingCall(self.myloopingCall)
self.lp.start(2)
reactor.callLater(0,self.myMainFunction,reactor)
def stop(self):
if self.lp is not None:
self.lp.stop()
print "I'm done"
if __name__ == '__main__':
myproc = MyProcess()
from twisted.internet import reactor
reactor.callWhenRunning(myproc.start,reactor)
reactor.addSystemEventTrigger('during','shutdown',myproc.stop)
reactor.callLater(10,reactor.stop)
reactor.run()
$ python bleh.py I have 0 stats I have 33375 stats I have 66786 stats I have 100254 stats I have 133625 stats I'm done