CherryPy会干扰Twisted在Windows上的关闭

编程入门 行业动态 更新时间:2024-10-25 18:27:06
本文介绍了CherryPy会干扰Twisted在Windows上的关闭的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我有一个运行Twisted的应用程序,它是在启动了其他一些线程(包括CherryPy Web服务器)之后,通过在主线程中使用 reactor.run()来启动反应堆的.这是一个在Linux而非Windows上按Ctrl + C会完全关闭的程序:

来自线程导入线程从信号导入信号SIGINT导入cherrypy来自twist.internet进口反应堆从twisted.web.client导入getPagedef停止(信号,帧):cherrypy.engine.exit()Reactor.CallFromThread(reactor.stop)信号(SIGINT,停止)类根:@ cherrypy.exposedef索引(自己):Reactor.callFromThread(启动)返回"Hello World!"cherrypy.server.socket_host ="0.0.0.0"线程(target = cherrypy.quickstart,args = [Root()]).start()def print_page(html):打印(HTML)def kickoff():getPage("acpstats/account/login").addCallback(print_page)react.run()

我相信CherryPy是这里的罪魁祸首,因为这是我写的没有CherryPy的另一个程序,当按下Ctrl + C时,它在Linux和Windows上都可以正常关机:

从时间导入睡眠从线程导入线程从信号导入信号SIGINT来自twist.internet进口反应堆从twisted.web.client导入getPagekeep_going =真def停止(信号,帧):全球保持keep_going =假Reactor.CallFromThread(reactor.stop)信号(SIGINT,停止)def print_page(html):打印(HTML)def kickoff():getPage("acpstats/account/login").addCallback(print_page)defperiod_downloader():在keep_going时:Reactor.callFromThread(启动)睡眠(5)线程(target = periodic_downloader).start()react.run()

有人知道这个问题是什么吗?这是我的难题:

  • 在Linux上一切正常
  • 在Windows上,当CherryPy未运行时,我可以使用 reactor.callFromThread 从信号处理程序中调用函数
  • CherryPy运行时,我使用信号处理程序中的 reactor.callFromThread 调用的函数将永远不会执行(我已确认信号处理程序本身确实会被调用)

对此我该怎么办?如何在运行CherryPy时从信号处理程序中关闭Twisted在Windows上?这是一个错误,还是我只是错过了这两个项目中任何一个的文档的重要部分?

解决方案

默认情况下,CherryPy在调用quickstart时会处理信号.在您的情况下,您应该只展开快速启动(仅几行),然后选择即可.基本上,这是快速入门在中继中的作用:

如果配置:cherrypy.config.update(config)tree.mount(root,script_name,config)如果hasattr(engine,"signal_handler"):engine.signal_handler.subscribe()如果hasattr(engine,"console_control_handler"):engine.console_control_handler.subscribe()启动引擎()engine.block()

在您的情况下,您不需要信号处理程序,因此可以将其省略.如果您不是从主线程启动CherryPy,也不需要调用engine.block.Engine.block()只是使主线程不立即终止的一种方法,而是等待进程终止(这是为了使autoreload可靠地工作;某些平台存在从主线程以外的任何线程调用execv的问题).

如果删除block()调用,则甚至不需要在quickstart周围使用Thread().因此,替换您的行:

Thread(target = cherrypy.quickstart,args = [Root()]).start()

具有:

cherrypy.tree.mount(Root())cherrypy.engine.start()

I've got an application that runs Twisted by starting the reactor with reactor.run() in my main thread after starting some other threads, including the CherryPy web server. Here's a program that shuts down cleanly when Ctrl+C is pressed on Linux but not on Windows:

from threading import Thread from signal import signal, SIGINT import cherrypy from twisted.internet import reactor from twisted.web.client import getPage def stop(signum, frame): cherrypy.engine.exit() reactor.callFromThread(reactor.stop) signal(SIGINT, stop) class Root: @cherrypy.expose def index(self): reactor.callFromThread(kickoff) return "Hello World!" cherrypy.server.socket_host = "0.0.0.0" Thread(target=cherrypy.quickstart, args=[Root()]).start() def print_page(html): print(html) def kickoff(): getPage("acpstats/account/login").addCallback(print_page) reactor.run()

I believe that CherryPy is the culprit here, because here's a different program that I wrote without CherryPy that does shutdown cleanly on both Linux and Windows when Ctrl+C is pressed:

from time import sleep from threading import Thread from signal import signal, SIGINT from twisted.internet import reactor from twisted.web.client import getPage keep_going = True def stop(signum, frame): global keep_going keep_going = False reactor.callFromThread(reactor.stop) signal(SIGINT, stop) def print_page(html): print(html) def kickoff(): getPage("acpstats/account/login").addCallback(print_page) def periodic_downloader(): while keep_going: reactor.callFromThread(kickoff) sleep(5) Thread(target=periodic_downloader).start() reactor.run()

Does anyone have any idea what the problem is? Here's my conundrum:

  • On Linux everything works
  • On Windows, I can call functions from signal handlers using reactor.callFromThread when CherryPy is not running
  • When CherryPy is running, no function that I call using reactor.callFromThread from a signal handler will ever execute (I've verified that the signal handler itself does get called)

What can I do about this? How can I shut down Twisted on Windows from a signal handler while running CherryPy? Is this a bug, or have I simply missed some important part of the documentation for either of these two projects?

解决方案

CherryPy handles signals by default when you call quickstart. In your case, you should probably just unroll quickstart, which is only a few lines, and pick and choose. Here's basically what quickstart does in trunk:

if config: cherrypy.config.update(config) tree.mount(root, script_name, config) if hasattr(engine, "signal_handler"): engine.signal_handler.subscribe() if hasattr(engine, "console_control_handler"): engine.console_control_handler.subscribe() engine.start() engine.block()

In your case, you don't need the signal handlers, so you can omit those. You also don't need to call engine.block if you're not starting CherryPy from the main thread. Engine.block() is just a way to make the main thread not terminate immediately, but instead wait around for process termination (this is so autoreload works reliably; some platforms have issues calling execv from any thread but the main thread).

If you remove the block() call, you don't even need the Thread() around quickstart. So, replace your line:

Thread(target=cherrypy.quickstart, args=[Root()]).start()

with:

cherrypy.tree.mount(Root()) cherrypy.engine.start()

更多推荐

CherryPy会干扰Twisted在Windows上的关闭

本文发布于:2023-10-08 02:32:40,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1471259.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:干扰   CherryPy   Windows   Twisted

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!