扭曲:正确捕获键盘中断和关闭
Posted
技术标签:
【中文标题】扭曲:正确捕获键盘中断和关闭【英文标题】:twisted: catch keyboardinterrupt and shutdown properly 【发布时间】:2011-03-28 01:50:08 【问题描述】:更新:为了便于阅读,这里是如何在反应器关闭之前添加回调:
reactor.addSystemEventTrigger('before', 'shutdown', callable)
原始问题如下。
如果我有一个连接到服务器的客户端,并且它在反应堆主循环中等待事件,当我按下 CTRL-C 时,我得到一个“与另一端的连接以非干净方式丢失:连接丢失。”如何设置它以便我知道何时发生 KeyboardInterrupt,以便我可以进行适当的清理并干净地断开连接?或者如果可能的话,我如何实现一种不涉及 CTRL-C 的更简洁的关机方式?
【问题讨论】:
甜蜜,首先点击谷歌搜索“关机前扭曲”! 【参考方案1】:如果你真的,真的想专门捕获 C-c,那么你可以用 Python 应用程序的通常方式来做这件事——使用signal.signal
为SIGINT
安装一个处理程序,它可以做任何你想做的事情。如果您从处理程序调用任何 Twisted API,请确保使用 reactor.callFromThread
,因为几乎所有其他 Twisted API 对于从信号处理程序调用都是不安全的。
但是,如果您真的只是对插入一些关闭时清理代码感兴趣,那么您可能希望使用IService.stopService
(或实现它的机制,reactor.addSystemEventTrigger
)来代替。
如果您使用的是twistd
,那么使用IService.stopService
很容易。您已经有一个 Application
对象,其中至少附加了一项服务。您可以使用自定义的stopService
方法添加另一个,该方法可以完成您的关机工作。允许该方法返回Deferred
。如果是这样,则关闭过程将暂停,直到Deferred
触发。这可以让您很好地清理连接,即使这涉及更多的网络(或任何其他异步)操作。
如果你不使用twistd
,那么直接使用reactor.addSystemEventTrigger
可能更容易。您可以安装一个 before shutdown 触发器,该触发器将在与 IService.stopService
相同的情况下被调用。此触发器(任何可调用对象)也可以返回 Deferred
以延迟关闭。这是通过调用reactor.addSystemEventTrigger('before', 'shutdown', callable)
来完成的(有时在启动关闭之前,因此在发生关闭时它已经注册)。
service.tac 给出了创建和使用自定义服务的示例。
wxacceptance.py 给出了一个使用addSystemEventTrigger
并将关机延迟(任意)三秒的示例。
这两种机制都会在反应器停止时向您发出通知。这可能是由于 C-c 击键,也可能是因为有人使用了 kill -INT ...
,或者可能是因为某处调用了 reactor.stop()
。它们都导致反应堆关闭,反应堆关闭总是处理关闭事件触发器。
【讨论】:
完美!就像我喜欢的那样工作。现在经过几个月的丑陋清理,它终于变得又漂亮又漂亮了......【参考方案2】:我不确定您是在谈论您编写的客户端还是服务器。
无论如何,'CTRL-C' 没有错。
如果您将服务器编写为应用程序。从twisted.application.service.Service
继承并定义startService
和stopService
。维护活动协议实例的列表。使用stopService
浏览它们并优雅地关闭它们。
如果你有一个客户端,你也可以继承Service
,但是使用reactor.addSystemEventTrigger('before','shutdown',myCleanUpFunction)
会更简单,并在这个函数中优雅地关闭连接。
【讨论】:
以上是关于扭曲:正确捕获键盘中断和关闭的主要内容,如果未能解决你的问题,请参考以下文章
显示键盘 + iPad 时 UIPopoverView 变得扭曲