2009-07-02 67 views
7

我有一个应用程序在启动一些其他线程(包括CherryPy Web服务器)后,在我的主线程中启动反应器并运行reactor.run()来运行Twisted。下面是当按下Ctrl + C键的Linux,但无法在Windows干净关闭的程序:CherryPy干扰在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("http://acpstats/account/login").addCallback(print_page) 

reactor.run() 

相信的CherryPy是罪魁祸首在这里,因为这里有我没有的CherryPy写了一个不同的程序,它关机干净在Linux和Windows时按下Ctrl + C键:

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("http://acpstats/account/login").addCallback(print_page) 

def periodic_downloader(): 
    while keep_going: 
     reactor.callFromThread(kickoff) 
     sleep(5) 

Thread(target=periodic_downloader).start() 
reactor.run() 

没有人有任何的想法是什么问题?这里是我的难题:

  • 在Linux一切正常
  • 在Windows上,我可以使用reactor.callFromThread调用从信号处理程序函数时的CherryPy未运行
  • 当CherryPy的运行过程中,没有功能了,我把使用reactor.callFromThread从信号处理程序将执行(我已验证信号处理程序本身确实被调用)

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

回答

14

当您调用快速启动时,CherryPy默认处理信号。在你的情况下,你应该展开快速入门,这只是几行,然后挑选。这里的基本上是快速入门确实在后备箱:

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() 

在你的情况,你不需要的信号处理程序,所以你可以省略这些。如果你没有从主线程启动CherryPy,你也不需要调用engine.block。 Engine.block()只是使主线程不会立即终止的一种方式,而是等待进程终止(这是因为autoreload可靠地工作;某些平台在除主线程之外的任何线程中调用execv时都存在问题)。

如果您删除了block()调用,则甚至不需要围绕快速启动的Thread()。因此,更换您的线路:

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

有:

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

非常感谢!你的回答写得非常好,而且乐于助人,所以我为了给你50个声望开了一个奖励。 – 2009-07-06 14:08:48