螺纹扭曲...如何正确使用它们?
我需要编写一个运行两个线程的简单应用程序: - 线程 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 安装它们,我不想开始从随机网页下载和使用一些随机脚本)。
I need to write a simple app that runs two threads:
- thread 1: runs at timed periods, let's say every 1 minute
- thread 2: just a 'normal' while True loop that does 'stuff'
if not the requirement to run at timed interval I would have not looked at twisted at all, but simple sleep(60) is not good enough and construction like:
l = task.LoopingCall(timed_thread)
l.start(60.0)
reactor.run()
Looked really simple to achieve what I wanted there.
Now, how do I 'properly' add another thread?
I see two options here:
- Use threading library and run two 'python threads' one executing my while loop, and another running reactor.run(). But Google seems to object this approach and suggests using twisted threading
- Use twisted threading. That's what I've tried, but somehow this looks bit clumsy to me.
Here's what I came up with:
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()
That seems to work, but! I can't stop the app. If I press ^C it wouldn't do anything (without 'callInThread' it just stops as you'd expect it to). ^Z bombs out to shell, and if I then do 'kill %1' it seems to kill the process (shell reports that), but the 'normal' thread keeps on running. kill PID wouldn't get rid of it, and the only cure is kill -9. Really strange.
So. What am I doing wrong? Is it a correct approach to implement two threads in twisted? Should I not bother with twisted? What other 'standard' alternatives are to implement timed calls? ('Standard' I mean I can easy_install or yum install them, I don't want to start downloading and using some random scripts from random web pages).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您没有解释为什么这里实际上需要线程。如果您有的话,我也许能够解释为什么您不需要它们。 ;)
除此之外,我可以确认您对事物的基本理解是正确的。不过,我可以澄清的一个可能的误解是“python 线程”和“Twisted 线程”完全不同的概念。他们不是。 Python提供了一个线程库。 Twisted 的所有线程 API 都是根据 Python 线程库实现的。只是API不同。
就关闭而言,您有两种选择。
reactor.addSystemEventTrigger('before', 'shutdown', f)
添加 Twisted 关闭挂钩。在该钩子中,与工作线程通信并告诉它关闭。例如,您可以在 Twisted 线程和工作线程之间共享一个threading.Event
并让钩子设置
它。工作线程可以定期检查它是否已设置,并在发现已设置时退出。除了不崩溃之外,这还比守护线程有另一个优势 - 它允许您在进程退出之前在工作线程中运行一些清理或终结代码。You didn't explain why you actually need threads here. If you had, I might have been able to explain why you don't need them. ;)
That aside, I can confirm that your basic understanding of things is correct. One possible misunderstanding I can clear up, though, is the notion that "python threads" and "Twisted threads" are at all different from each other. They're not. Python provides a threading library. All of Twisted's thread APIs are implemented in terms of Python's threading library. Only the API is different.
As far as shutdown goes, you have two options.
reactor.addSystemEventTrigger('before', 'shutdown', f)
. In that hook, communicate with the work thread and tell it to shut down. For example, you could share athreading.Event
between the Twisted thread and your work thread and have the hookset
it. The work thread can periodically check to see if it has been set and exit when it notices that it has been. Aside from not crashing, this gives another advantage over daemon threads - it will let you run some cleanup or finalization code in your work thread before the process exits.假设你的 main 是相对非阻塞的:
Assuming that your main is relatively non-blocking: