扭曲:正确捕获键盘中断和关闭

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.signalSIGINT 安装一个处理程序,它可以做任何你想做的事情。如果您从处理程序调用任何 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 继承并定义startServicestopService。维护活动协议实例的列表。使用stopService 浏览它们并优雅地关闭它们。

如果你有一个客户端,你也可以继承Service,但是使用reactor.addSystemEventTrigger('before','shutdown',myCleanUpFunction)会更简单,并在这个函数中优雅地关闭连接。

【讨论】:

以上是关于扭曲:正确捕获键盘中断和关闭的主要内容,如果未能解决你的问题,请参考以下文章

当键盘上没有中断键时,excel VBA中断执行[关闭]

为collectionView正确关闭键盘

显示键盘 + iPad 时 UIPopoverView 变得扭曲

如何使用JavaScript捕获iOS上的隐藏键盘事件

iOS:UIPopoverController 内的人物选择器,搜索键盘扭曲弹出框

使用钢琴键盘作为电脑键盘[关闭]